Joe的Erlang websocket示例的Python示例

时间:2010-01-28 08:58:50

标签: python websocket

我刚刚从Joe Armstrong's blog开始处理erlang websockets示例我仍然是erlang的新手所以我决定在python中编写一个简单的服务器来帮助我了解websockets(希望有些是erlang)通过解释乔的代码)。我有两个问题:

1)我从页面收到的数据包含一个'ÿ'作为最后一个字符。这不会出现在erlang版本中,我无法解决它来自哪里固定 - 这是因为在utf-8和我编码的字符串没有解码它们

2)我似乎是从服务器发送数据(通过websocket) - 可以通过查看client.send()生成的字节数来确认。但页面上没有任何内容出现。 已修复,我没有正确编码字符串

我已经放了所有代码here。这是我的python版本,因为我错过了任何明显的

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()

对于那些没有通过joe示例但仍希望提供帮助的人,您只需要通过Web服务器提供interact.html,然后启动您的服务器(代码假定Web服务器在localhost:8888上运行)

3 个答案:

答案 0 :(得分:10)

对于那些感兴趣的人来说,这就是解决方案

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()

编辑liwp的请求:

您可以查看文件here的差异。基本上我的问题是我在发送/接收之前解码/编码字符串的方式。在谷歌代码上有一个websocket module正在为Apache工作,我常常找出我出错的地方。

答案 1 :(得分:0)

感谢您分享代码。我遇到了一个在Windows中运行此代码的问题。我认为这对那些仍在计算的人有用。

  1. 我把这个空格弄得一团糟,所以它标榜'升级:WebSocket'

  2. 确保您的托管页面与Origin匹配,在这种情况下,它是“http://localhost:8888

  3. 现在它对我来说很漂亮。

答案 2 :(得分:0)

Eventlet内置了websocket支持,而stargate是一个使用websockets和金字塔Web框架的包:http://boothead.github.com/stargate/