Я создаю приватный чат и звоню как по голосовой, так и по видеосвязи, которые проповедуют конфиденциальность, с полной сквозной конфиденциальностью, никакие сообщения не сохраняются или не сохраняются на сервере, и каждое сообщение зашифровано, поэтому никто не сможет его взломать, каждый пользователь получил право вести собственный чат, теперь, что бы я ни делал, чат не работает, я чувствую, что мой файл my Consumer.py написан не очень хорошо, я хочу, чтобы пользователи общались и звонили друг другу по видеосвязи, но они не общаются например, пользователи не общаются друг с другом, как будто они не находятся в одной комнате
class SecureChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.user = self.scope['user']
self.friend_username = self.scope['url_route']['kwargs']['username']
if not self.user.is_authenticated:
await self.close()
return
try:
# Create a shared room name between both users for proper communication
self.room_name = f"chat_{'_'.join(sorted([self.user.username, self.friend_username]))}"
await self.channel_layer.group_add(self.room_name, self.channel_name)
await self.update_user_status(online=True)
await self.accept()
logger.info(f"WebSocket connection established for user {self.user.username} in room {self.room_name}")
except Exception as e:
logger.error(f"Error during WebSocket connection: {e}")
await self.close()
async def disconnect(self, close_code):
await self.channel_layer.group_discard(self.room_name, self.channel_name)
await self.update_user_status(online=False)
logger.info(f"WebSocket disconnected for user {self.user.username}")
async def receive(self, text_data):
"""
Handle incoming WebSocket messages. Distinguish between message events and WebRTC events.
"""
try:
data = json.loads(text_data)
message_type = data.get('type')
logger.info(f"Received message of type '{message_type}' from {self.user.username}")
except json.JSONDecodeError as e:
logger.error(f"Error parsing message data: {e}")
await self.send_error("Invalid JSON format.")
return
if message_type == 'message':
await self.handle_message_event(data)
elif message_type in ['call-offer', 'call-answer', 'ice-candidate']:
await self.handle_webrtc_event(data)
elif message_type == 'public-key':
await self.handle_key_exchange(data)
else:
logger.warning(f"Unknown message type received: {message_type}")
await self.send_error("Unknown message type.")
async def handle_message_event(self, data):
"""
Handle secure chat message events between two users using end-to-end encryption.
"""
message = data.get('message')
recipient_username = data.get('to')
if message and recipient_username:
logger.info(f"Forwarding encrypted message from {self.user.username} to {recipient_username}")
await self.send_encrypted_message(recipient_username, message)
async def handle_webrtc_event(self, data):
"""
Handle WebRTC signaling for peer-to-peer voice and video calls.
"""
recipient_username = data.get('to')
event_type = data['type']
event_data = data['data']
logger.info(f"Forwarding WebRTC signal '{event_type}' from {self.user.username} to {recipient_username}")
await self.forward_webrtc_signal(recipient_username, event_type, event_data)
async def handle_key_exchange(self, data):
"""
Handle the exchange of public keys for secure messaging.
"""
recipient_username = data.get('to')
public_key = data.get('publicKey')
if public_key and recipient_username:
logger.info(f"Forwarding public key from {self.user.username} to {recipient_username}")
await self.send_public_key(recipient_username, public_key)
async def send_encrypted_message(self, recipient_username, message):
"""
Send an encrypted message to the recipient via the WebSocket group.
"""
await self.channel_layer.group_send(
f"chat_{'_'.join(sorted([self.user.username, recipient_username]))}",
{
'type': 'chat_message',
'message': message,
'sender': self.user.username
}
)
async def chat_message(self, event):
"""
Deliver the chat message to the WebSocket client.
"""
await self.send(text_data=json.dumps({
'type': 'message',
'message': event['message'],
'sender': event['sender']
}))
async def forward_webrtc_signal(self, recipient_username, signal_type, data):
"""
Forward WebRTC signaling data to the specified recipient.
"""
await self.channel_layer.group_send(
f"chat_{'_'.join(sorted([self.user.username, recipient_username]))}",
{
'type': signal_type,
'data': data,
'sender': self.user.username
}
)
async def call_offer(self, event):
"""
Send a WebRTC call offer to the recipient.
"""
await self.send(text_data=json.dumps({
'type': 'call-offer',
'offer': event['data'],
'from': event['sender']
}))
async def call_answer(self, event):
"""
Send a WebRTC call answer to the recipient.
"""
await self.send(text_data=json.dumps({
'type': 'call-answer',
'answer': event['data'],
'from': event['sender']
}))
async def ice_candidate(self, event):
"""
Send an ICE candidate to the recipient to assist in the WebRTC connection setup.
"""
await self.send(text_data=json.dumps({
'type': 'ice-candidate',
'candidate': event['data'],
'from': event['sender']
}))
async def send_public_key(self, recipient_username, public_key):
"""
Send the public key to the recipient via the WebSocket group.
"""
await self.channel_layer.group_send(
f"chat_{'_'.join(sorted([self.user.username, recipient_username]))}",
{
'type': 'public-key',
'publicKey': public_key,
'sender': self.user.username
}
)
async def public_key(self, event):
"""
Deliver the public key to the WebSocket client.
"""
await self.send(text_data=json.dumps({
'type': 'public-key',
'publicKey': event['publicKey'],
'sender': event['sender']
}))
@database_sync_to_async
def update_user_status(self, online):
"""
Update the user's online status in the database.
"""
try:
user_profile = UserProfile.objects.get(username=self.user.username)
user_profile.online = online
user_profile.save()
except UserProfile.DoesNotExist:
logger.error(f"User profile not found for {self.user.username}")
async def send_error(self, message):
"""
Send an error message to the client.
"""
await self.send(text_data=json.dumps({
'status': 'error',
'message': message
}))
это тоже мой код JavaScript,
document.addEventListener("DOMContentLoaded", function () {
// WebSocket connection setup
const socketProtocol = window.location.protocol === "https:" ? "wss" : "ws";
const chatSocket = new WebSocket(`${socketProtocol}://${window.location.host}/ws/chat/${friendUsername}/`);
chatSocket.onopen = () => {
console.log("WebSocket connection established.");
const userStatusElement = document.getElementById(`status-${friendUsername}`);
if (userStatusElement) {
userStatusElement.textContent = 'Online';
}
};
chatSocket.onclose = () => {
console.log("WebSocket connection closed.");
const userStatusElement = document.getElementById(`status-${friendUsername}`);
if (userStatusElement) {
userStatusElement.textContent = 'Offline';
}
};
chatSocket.onerror = (error) => {
console.error("WebSocket error:", error);
};
// WebRTC configuration
const peerConnectionConfig = {
iceServers: [{ urls: "stun:stun.l.google.com:19302" }]
};
let peerConnection = new RTCPeerConnection(peerConnectionConfig);
// Handle ICE candidate events
peerConnection.onicecandidate = (event) => {
if (event.candidate) {
chatSocket.send(JSON.stringify({
type: 'ice-candidate',
data: event.candidate,
to: friendUsername
}));
}
};
// Handle remote video stream
peerConnection.ontrack = (event) => {
const remoteStream = event.streams[0];
const remoteVideo = document.getElementById('remoteVideo');
remoteVideo.srcObject = remoteStream;
remoteVideo.play();
};
// Function to securely exchange public keys with the other user
async function securelyExchangeKeys() {
const keyPair = await generateECDHKeys();
localECDHPrivateKey = keyPair.privateKey;
const exportedPublicKey = await window.crypto.subtle.exportKey('raw', keyPair.publicKey);
// Send the public key to the friend via WebSocket for exchange
chatSocket.send(JSON.stringify({
type: 'public-key',
publicKey: Array.from(new Uint8Array(exportedPublicKey)), // Converting to array for transmission
to: friendUsername
}));
console.log('Public key sent to the friend for secure key exchange.');
}
// Function to send an encrypted message to the server
function sendMessageToServer(ciphertext, iv) {
if (chatSocket.readyState === WebSocket.OPEN) {
chatSocket.send(JSON.stringify({
type: 'message',
message: ciphertext,
iv: iv,
to: friendUsername
}));
console.log("Message sent to the server.");
} else {
console.error("WebSocket is not open. Unable to send message.");
alert("Connection lost. Please wait while we try to reconnect.");
}
}
// Send encrypted chat message when the send button is clicked
document.getElementById('send-button').addEventListener('click', async () => {
const messageInput = document.getElementById('message-input');
const message = messageInput.value.trim();
if (message !== '') {
try {
if (!sharedKey) {
console.error("Shared key is not defined. Cannot encrypt the message.");
alert("Encryption key not ready. Please wait before sending messages.");
return;
}
const { ciphertext, iv } = await encryptMessage(sharedKey, message);
sendMessageToServer(ciphertext, iv);
messageInput.value = ''; // Clear the input field
displayLocalMessage(message); // Display the message in the sender's chat log
} catch (encryptionError) {
console.error("Error during message encryption:", encryptionError);
alert("Failed to send message. Please try again.");
}
}
});
// WebSocket message handling
chatSocket.onmessage = async function (event) {
const data = JSON.parse(event.data);
if (data.type === 'public-key') {
console.log('Received public key from the friend.');
const publicKeyArray = new Uint8Array(data.publicKey);
try {
const importedPublicKey = await window.crypto.subtle.importKey(
'raw',
publicKeyArray.buffer,
{ name: 'ECDH', namedCurve: 'P-256' },
true,
[]
);
sharedKey = await deriveSharedSecret(localECDHPrivateKey, importedPublicKey);
console.log('Shared key successfully derived for secure messaging!');
} catch (keyError) {
console.error("Error deriving shared key:", keyError);
}
} else if (data.type === 'message') {
if (sharedKey) {
const decryptedMessage = await decryptMessage(sharedKey, data.message, data.iv);
displayDecryptedMessage(data.sender, decryptedMessage);
} else {
console.error("Shared key is not defined. Cannot decrypt the message.");
}
} else {
handleWebRTCSignal(data); // Handle WebRTC signals like calls, answers, etc.
}
};
// Event listeners for audio and video calls
document.getElementById('voice-call').addEventListener('click', startVoiceCall);
document.getElementById('video-call').addEventListener('click', startVideoCall);
// Start a video call
async function startVideoCall() {
const localStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
localStream.getTracks().forEach(track => peerConnection.addTrack(track, localStream));
displayLocalVideoStream(localStream);
const offer = await peerConnection.createOffer();
await peerConnection.setLocalDescription(offer);
chatSocket.send(JSON.stringify({
type: 'call-offer',
data: offer,
to: friendUsername
}));
}
// Start a voice call
async function startVoiceCall() {
const localStream = await navigator.mediaDevices.getUserMedia({ audio: true });
localStream.getTracks().forEach(track => peerConnection.addTrack(track, localStream));
displayLocalVideoStream(localStream);
const offer = await peerConnection.createOffer();
await peerConnection.setLocalDescription(offer);
chatSocket.send(JSON.stringify({
type: 'call-offer',
data: offer,
to: friendUsername
}));
}
// Handle WebRTC signaling messages for the call
async function handleWebRTCSignal(data) {
switch (data.type) {
case 'call-offer':
await peerConnection.setRemoteDescription(new RTCSessionDescription(data.data));
const answer = await peerConnection.createAnswer();
await peerConnection.setLocalDescription(answer);
chatSocket.send(JSON.stringify({
type: 'call-answer',
data: answer,
to: friendUsername
}));
break;
case 'call-answer':
await peerConnection.setRemoteDescription(new RTCSessionDescription(data.data));
break;
case 'ice-candidate':
if (data.data) {
await peerConnection.addIceCandidate(new RTCIceCandidate(data.data));
}
break;
default:
console.warn("Unhandled WebRTC signal:", data.type);
}
}
// Display local video stream
function displayLocalVideoStream(stream) {
const localVideo = document.getElementById('localVideo');
localVideo.srcObject = stream;
localVideo.play();
}
// Cleanup on page unload
window.addEventListener('beforeunload', () => {
sessionStorage.clear();
peerConnection.close();
});});
это также мой файл Chats.html
{% extends "chat/Base.html" %}
{% load static %}
{% block content %}
Friends
{{ friend.name }}
Offline
const friendUsername = "{{ friend.username }}"; // Assign friend's username to a JS variable
{% endblock %}
Подробнее здесь: https://stackoverflow.com/questions/790 ... each-other
Мои пользователи чата не подключаются друг к другу ⇐ Python
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Как удалить контуры, расположенные слишком близко друг к другу по осям X OPENCV — PYTHON
Anonymous » » в форуме Python - 0 Ответы
- 26 Просмотры
-
Последнее сообщение Anonymous
-