Форум сайта python.su
Всем добрый день. Пытаюсь сделать простой эхо websocket-сервер. За основу взял этот код. Однако он работает со старым протоколом-76. Начал переделывать под протокол 07, соединение проходит успешно, однако сообщения не передаются. Искал в чем может быть причина, но так и не нашел. Я новичек в питоне, поэтому решил спросить у вас: что я сделал не так? Заранее благодарен. Код привожу ниже:
import time import struct import socket import hashlib import sys from select import select import re import logging from threading import Thread import signal from base64 import b64encode class WebSocket(object): handshake = ( "HTTP/1.1 101 Switching Protocols\r\n" "Upgrade: websocket\r\n" "Connection: Upgrade\r\n" "Sec-WebSocket-Accept: %(accept)s\r\n" "Sec-WebSocket-Protocol: chat\r\n" "\r\n" ) def __init__(self, client, server): self.client = client self.server = server self.handshaken = False self.header = "" self.data = "" def feed(self, data): if not self.handshaken: self.header += data if self.header.find('\r\n\r\n') != -1: parts = self.header.split('\r\n\r\n', 1) self.header = parts[0] if self.dohandshake(self.header, parts[1]): logging.info("Handshake successful") self.handshaken = True else: self.data += data msgs = self.data.split('\xff') self.data = msgs.pop() for msg in msgs: if msg[0] == '\x00': self.onmessage(msg[1:]) def dohandshake(self, header, key=None): logging.debug("Begin handshake: %s" % header) for line in header.split('\r\n')[1:]: name, value = line.split(': ', 1) if name.lower() == "sec-websocket-key": key_accept = value+"258EAFA5-E914-47DA-95CA-C5AB0DC85B11" key_accept = hashlib.sha1(key_accept).digest() key_accept = b64encode(key_accept) handshake = WebSocket.handshake % { 'accept': key_accept } else: logging.warning("Not using challenge + response") handshake = WebSocket.handshake % { 'accept': key_accept } logging.debug("Sending handshake %s" % handshake) self.client.send(handshake) return True def onmessage(self, data): logging.info("Got message: %s" % data) def send(self, data): logging.info("Sent message: %s" % data) self.client.send("\x00%s\xff" % data) def close(self): self.client.close() class WebSocketServer(object): def __init__(self, bind, port, cls): self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.socket.bind((bind, port)) self.bind = bind self.port = port self.cls = cls self.connections = {} self.listeners = [self.socket] def listen(self, backlog=5): self.socket.listen(backlog) logging.info("Listening on %s" % self.port) self.running = True while self.running: rList, wList, xList = select(self.listeners, [], self.listeners, 1) for ready in rList: if ready == self.socket: logging.debug("New client connection") client, address = self.socket.accept() fileno = client.fileno() self.listeners.append(fileno) self.connections[fileno] = self.cls(client, self) else: logging.debug("Client ready for reading %s" % ready) client = self.connections[ready].client data = client.recv(1024) fileno = client.fileno() if data: self.connections[fileno].feed(data) else: logging.debug("Closing client %s" % ready) self.connections[fileno].close() del self.connections[fileno] self.listeners.remove(ready) for failed in xList: if failed == self.socket: logging.error("Socket broke") for fileno, conn in self.connections: conn.close() self.running = False if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG, format="%(asctime)s - %(levelname)s - %(message)s") server = WebSocketServer("localhost", 9999, WebSocket) server_thread = Thread(target=server.listen, args=[5]) server_thread.start() # Add SIGINT handler for killing the threads def signal_handler(signal, frame): logging.info("Caught Ctrl+C, shutting down...") server.running = False sys.exit() signal.signal(signal.SIGINT, signal_handler) while True: time.sleep(100)
Офлайн