2010-01-28 19 views
9

He estado trabajando con el ejemplo de erlang websockets de Joe Armstrong's blog Todavía soy bastante nuevo en erlang, así que decidí escribir un servidor simple en python que me ayudara a aprender sobre websockets (y con suerte algunos erlang interpretando el código de Joe). Tengo dos problemas:Ejemplo de Python del paquete websocket Erlang de Joe

1) Los datos que recibo de la página incluyen un 'ÿ' como el último carácter. Esto no aparece en la versión de Erlang y no puedo averiguar dónde está viniendo de Fijo - Esto se debió a las cuerdas donde codificados en UTF-8 y no me decodificarlos

2) que parecen para enviar datos desde el servidor (a través del websocket), lo que se puede confirmar mirando cuántos bytes hace client.send(). Pero nada está apareciendo en la página. Solucionado, no estaba codificando la cadena correctamente

He puesto todo el código here. Aquí está mi versión de pitón en caso que me falta algo obvio

import threading 
import socket 

def start_server(): 
    tick = 0 
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    sock.bind(('localhost', 1234)) 
    sock.listen(100) 
    while True: 
     print 'listening...' 
     csock, address = sock.accept() 
     tick+=1 
     print 'connection!' 
     handshake(csock, tick) 
     print 'handshaken' 
     while True: 
      interact(csock, tick) 
      tick+=1 

def handshake(client, tick): 
    our_handshake = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"+"Upgrade:  WebSocket\r\n"+"Connection: Upgrade\r\n"+"WebSocket-Origin:  http://localhost:8888\r\n"+"WebSocket-Location: "+" ws://localhost:1234/websession\r\n\r\n" 
    shake = client.recv(255) 
    print shake 
    client.send(our_handshake) 

def interact(client, tick): 
    data = client.recv(255) 
    print 'got:%s' %(data) 
    client.send("clock ! tick%d\r" % (tick)) 
    client.send("out ! recv\r") 

if __name__ == '__main__': 
    start_server() 

Para aquellos que no han ejecutado a través del ejemplo de Joe, pero todavía quiere ayudar, sólo tiene que servir hasta interact.html través de un servidor web y luego comenzar su servidor (el código se supone que el servidor web se ejecuta en localhost: 8888)

Respuesta

10

para aquellos que estén interesados ​​esta era la solución

import threading 
import socket 

def start_server(): 
    tick = 0 
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    sock.bind(('localhost', 1234)) 
    sock.listen(100) 
    while True: 
     print 'listening...' 
     csock, address = sock.accept() 
     tick+=1 
     print 'connection!' 
     handshake(csock, tick) 
     print 'handshaken' 
     while True: 
      interact(csock, tick) 
      tick+=1 


def send_data(client, str): 
    #_write(request, '\x00' + message.encode('utf-8') + '\xff') 
    str = '\x00' + str.encode('utf-8') + '\xff' 
    return client.send(str) 
def recv_data(client, count): 
    data = client.recv(count)  
    return data.decode('utf-8', 'ignore') 

def handshake(client, tick): 
    our_handshake = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"+"Upgrade:  WebSocket\r\n"+"Connection: Upgrade\r\n"+"WebSocket-Origin: http://localhost:8888\r\n"+"WebSocket-Location: "+" ws://localhost:1234/websession\r\n\r\n" 
    shake = recv_data(client, 255) 
    print shake 
    #We want to send this without any encoding 
    client.send(our_handshake) 

def interact(client, tick): 
    data = recv_data(client, 255) 
    print 'got:%s' %(data) 
    send_data(client, "clock ! tick%d" % (tick)) 
    send_data(client, "out ! %s" %(data)) 

if __name__ == '__main__': 
    start_server() 

de edición para la petición de liwp:

Puede ver una diferencia del archivo here. Esencialmente, mi problema era la forma en que estaba decodificando/codificando cadenas antes de enviar/recibir. Hay un websocket module en el que se está trabajando para Apache en el código de Google, que usé para averiguar dónde me estaba yendo mal.

+0

Cuidado a ser un poco más específico? Es un poco difícil tratar de distinguir los dos archivos en una página web. – liwp

0

Gracias por compartir el código. Me encontré con un problema al ejecutar este código en Windows. Lo cual creo que podría ayudar a las personas que todavía están pensando.

  1. I strink el espacio, de modo que bacame 'Upgrade: WebSocket'

  2. Asegúrese de que su página de alojamiento es vincular el origen, que en este caso se trata de 'http://localhost:8888'

Funciona muy bien para mí ahora.