Joe 的 Erlang websocket 示例的 Python 示例

Posted

技术标签:

【中文标题】Joe 的 Erlang websocket 示例的 Python 示例【英文标题】:Python example of Joe's Erlang websocket example 【发布时间】:2010-01-28 08:58:50 【问题描述】:

我刚刚研究了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 上运行)

【问题讨论】:

【参考方案1】:

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

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 在谷歌代码上工作,我过去常常找出我哪里出错了。

【讨论】:

想更具体一点吗?尝试在网页上区分这两个文件有点困难。【参考方案2】:

感谢分享代码。我在 Windows 中运行此代码时遇到了一个问题。我认为这可能对仍在思考的人有所帮助。

    我删除了空格,所以它变成了“升级:WebSocket”

    确保您的托管页面与 Origin 匹配,在本例中为“http://localhost:8888”

现在对我来说效果很好。

【讨论】:

【参考方案3】:

Eventlet 内置了 websocket 支持,stargate 是一个用于将 websockets 与金字塔 web 框架一起使用的包:http://boothead.github.com/stargate/

【讨论】:

以上是关于Joe 的 Erlang websocket 示例的 Python 示例的主要内容,如果未能解决你的问题,请参考以下文章

程序员的损失!Erlang 之父 Joe Armstrong 离世

编程语言 Erlang 发明人 Joe Armstrong 去世

大神陨落,Erlang 之父 Joe Armstrong 离世

软件: Erlang 语言作者 Joe Armstrong 去世

开发者日报丨Erlang 之父 Joe Armstrong 逝世,享年 68 岁

499元在SDCC遇见Erlang之父Joe Armstrong