сервер websocket на python.problems - PullRequest
0 голосов
/ 10 марта 2012

Передо мной стояла задача реализовать простые серверные дескрипторы для Python с поддержкой websocket. Конечно, я знаю о tornadoIO, но проблема в том, чтобы реализовать его. Шаг соединения и Рукопожатие (обмен секретными ключами) я сделал, но тогда у меня проблемы. 1) Сообщение от клиента (браузера) действительно приходит, но они закодированы. Я нашел информацию об этом, но не мог понять, как их расшифровать. Документация говорит, что сообщение скрыто под маской (как я понимаю, это XOR), но ключ к открытию этой маски не указан клиентом (браузером), или я его не вижу. 2) сообщения, которые отправляет сервер, клиент (браузер) игнорируются. Отправка согласно документации

conn.send(bytes(0x00))
conn.send(u'test'.encode('utf-8'))
conn.send(bytes(0xFF))

загруженный исходный код здесь и я размещаю источник здесь

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import socket,sys,hashlib,time
from base64 import b64encode
from threading import Thread
#===================================
bindto=['127.3.1.4',80]
thr_kill=False

def getsett(text,ss,si,es):
#this function i'm use for cut strings by known patterns
   global getsett_i1,getsett_i2
   if text==None: return None
   if ss==None: return None
   if es==None: return None
   text1=text.lower()
   ss=ss.lower()
   es=es.lower()
   if ss!='': getsett_i1=text1.find(ss,si)
   else: getsett_i1=si
   if getsett_i1==-1: return None
   if es!='': getsett_i2=text1.find(es,getsett_i1+len(ss))
   else: getsett_i2=len(text1)
   if getsett_i2==-1: return None
   return text[getsett_i1+len(ss):getsett_i2]

def thr_waitclient():
   global bindto,thr_kill
   serv=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
   serv.bind((bindto[0],bindto[1]))
   while thr_kill==False:
      serv.listen(1)
      conn,adr=serv.accept()
      data=conn.recv(4096)
      print data
#checking connection type
      if getsett(data,'connection: ',0,"\r\n").lower()=='upgrade' and getsett(data,'upgrade: ',0,"\r\n").lower()=='websocket':
#handshake
         wbs=getsett(data,'Sec-WebSocket-Key: ',0,"\r\n")
         conn.send("HTTP/1.1 101 Web Socket Protocol Handshake\r\nUpgrade: WebSocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "+b64encode(hashlib.sha1(wbs+'258EAFA5-E914-47DA-95CA-C5AB0DC85B11').digest())+"\r\nSec-WebSocket-Origin: *\r\nAccess-Control-Allow-Origin: *\r\nOrigin: *\r\nAccess-Control-Allow-Credentials:true\r\nAccess-Control-Allow-Headers:content-type\r\n\r\n")
#wait for clien's messahe,then send response
         while True:
            print conn.recv(4096) #first problem:message is coded
            conn.send(bytes(0x00))
            conn.send(u'test'.encode('utf-8'))
            conn.send(bytes(0xFF))
            #second problem: client ignore message
            time.sleep(0.5)
      else:
         conn.close()
   serv.close()

Thread(None,thr_waitclient).start()
while thr_kill!=True:
   time.sleep(0.3)
sys.exit(0)

1 Ответ

2 голосов
/ 10 марта 2012

Существует два основных варианта протокола WebSocket.Ваш пример кода представляет собой смесь обоих, которые не будут работать ни для одного протокола.

В последних версиях Chrome, Firefox и IE10 используется более новый протокол HyBi / IETF.В старых версиях Chrome и текущих версиях Safari (для настольных и мобильных компьютеров) используется более старый протокол Hixie.

Протокол Hixie использовал «\ x00» для обозначения начала кадра и «\ xff» для обозначения конца кадра.Протокол Hixie не маскирует данные браузера от сервера.Существует две основные версии протокола Hixie: 75 и 76. Версия 76 содержит дополнительный фрагмент данных, который обменивается сразу после заголовков, но перед обычными кадрами.

В более новом протоколе HyBi / IETF используется 2-10-байтовый заголовок, который содержит длину полезной нагрузки и не имеет отдельного конечного маркера.В более новом протоколе данные полезной нагрузки от браузера к серверу маскируются с использованием 4-байтовой рабочей маски XOR.Первые 4 байта после заголовка являются маской в ​​случае браузера с сервером.Данные с сервера на браузер не маскируются.Заголовки и процесс рукопожатия также различаются для протокола HyBi.

Многие серверы WebSocket поддерживают версии протокола WebSocket как Hixie, так и HyBi / IETF (вы можете определить из заголовков, отправленных браузером, какую версию он использует).

Вот спецификации для различных версий протокола:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...