Exemplo de Python do exemplo de Joe's Erlang WebSocket
Pergunta
Acabei de trabalhar no exemplo de Erlang websockets de Blog de Joe Armstrong Ainda sou muito novo no Erlang, então decidi escrever um servidor simples no Python que ajudaria a me ensinar sobre o WebSockets (e espero que alguns Erlang interpretem o código de Joe). Estou tendo dois problemas:
1) Os dados que recebo da página incluem um '' 'como o último char. Isso não aparece na versão Erlang e eu não posso descobrir de onde vem Corrigido - isso ocorreu porque as cordas foram codificadas no UTF -8 e eu não as decodificava
2) Parece que estou enviando dados do servidor (através do WebSocket) - que podem ser confirmados analisando quantas bytes client.send () produz. Mas nada está aparecendo na página. Consertado, eu não estava codificando a string corretamente
Eu coloquei todo o código aqui. Aqui está minha versão python, caso estou perdendo qualquer coisa óbvia
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 quem não passou pelo exemplo de Joe, mas ainda quer ajudar, você só precisa servir interagir.html através de um servidor da web e depois iniciar seu servidor (o código assume que o servidor da web está em execução no localhost: 8888)
Solução
Para aqueles que estão interessados, essa foi a solução
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()
Editar para o pedido do LIWP:
Você pode ver um diferencial do arquivo aqui. Essencialmente, meu problema era a maneira como eu estava decodificando / codificando seqüências de codificação antes de enviar / receber. Há um Módulo WebSocket Ser trabalhado para o Apache no código do Google, que eu costumava descobrir onde estava dando errado.
Outras dicas
Obrigado por compartilhar o código. Eu encontrei um problema executando esse código no Windows. O que eu acho que pode ajudar para pessoas que ainda estão imaginando.
Eu estalo o espaço, para que ele bacame 'Atualização: WebSocket'
Certifique -se de que sua página de hospedagem esteja correspondendo à origem, que neste caso é 'http: // localhost: 8888'
Está funcionando lindamente para mim agora.
O Eventlet possui o WebSocket Support IN e Stargate é um pacote para usar o WebSockets com a estrutura da web pyramid: http://boothead.github.com/stargate/