Форум русскоязычного сообщества Ubuntu


Следите за новостями русскоязычного сообщества Ubuntu в Twitter-ленте @ubuntu_ru_loco

Автор Тема: Python - вебсокеты(websocket)  (Прочитано 2850 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн xmarat

  • Автор темы
  • Участник
  • *
  • Сообщений: 101
    • Просмотр профиля
Python - вебсокеты(websocket)
« : 06 Мая 2012, 20:29:49 »
Всем добрый вечер. Пытаюсь сделать простой эхо websocket-сервер. За основу взял этот код https://gist.github.com/512987. Однако он работает со старым протоколом-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)
« Последнее редактирование: 07 Мая 2012, 13:37:02 от xmarat »

Оффлайн Bers

  • Любитель
  • *
  • Сообщений: 60
    • Просмотр профиля
    • Домашняя страничка
Re: Python - вебсокеты(websocket)
« Ответ #1 : 09 Мая 2012, 11:27:32 »
Я бы посоветовал использовать торнадо - tornadoweb.org

Оффлайн xmarat

  • Автор темы
  • Участник
  • *
  • Сообщений: 101
    • Просмотр профиля
Re: Python - вебсокеты(websocket)
« Ответ #2 : 09 Мая 2012, 14:37:43 »
Начал использовать торнадо. Спасибо  :)

Вопрос из любопытства: насколько использование торнадо будет медленнее при высоких нагрузках или разницы не будет?

Возник вопрос про Eclipse+PyDev: для торнадо создал папки static и templates, после чего в папке создал файл index.html, открываю для редактирования, а синтаксис не подсвечивается. Пытался найти решение, но так и не нашел.

Оффлайн xmarat

  • Автор темы
  • Участник
  • *
  • Сообщений: 101
    • Просмотр профиля
Re: Python - вебсокеты(websocket)
« Ответ #3 : 10 Мая 2012, 21:46:18 »
Вопрос про Eclipse решил - оказалось не установлен плагин html, поставил и заработало.

 

Страница сгенерирована за 0.028 секунд. Запросов: 25.