我一直在用python3编写游戏服务器。我的目标是保持它的通信选项非常开放,以便多个不同的客户端可以轻松连接。目前所有的通信都是通过telnet使用miniboa。我想有选项允许基于web的客户端以及。似乎最简单的选择是允许websocket连接。我一直在玩的websockify工作,但我宁愿不使用代理,如果可能的话,因为所有的连接似乎来自代理。理想情况下,我想要的是我可以放入我的telnet服务器来识别websocket握手请求(与常规请求相比),返回正确的握手,然后保持连接继续,以便通过telnet和websocket发送/接收的命令是相同的。我还没有找到任何允许我自动执行此操作的东西,所以我一直在尝试编写自己的代码来识别websocket握手并以相应的握手回复。我看了很多其他的帖子和例子,特别是python websocket握手(RFC 6455),我修改并转换为以下测试程序
#!/usr/bin/env python3
from miniboa import TelnetServer
from base64 import b64encode
from hashlib import sha1
clientlist = []
def client_connects(client):
clientlist.append(client)
def client_disconnects(client):
clientlist.remove(client)
def process_clients():
for client in clientlist:
if client.active and client.cmd_ready:
total_cmd = client.get_command()
print("incoming = {}" .format(total_cmd))
if total_cmd.find(" ") != -1: # breaking apart incoming command
cmd, cmd_var = total_cmd.split(" ", 1)
else:
cmd = total_cmd
cmd_var = ""
if cmd == "Sec-WebSocket-Key:":
GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
cmd_var = cmd_var + GUID
encoded = cmd_var.encode('utf-8')
response_key = b64encode(sha1(encoded).digest())
websocket_answer = (
'HTTP/1.1 101 Switching Protocols',
'Upgrade: websocket',
'Connection: Upgrade',
'Sec-WebSocket-Accept: {key}rnrn',
)
handshake = 'rn'.join(websocket_answer).format(key=response_key)
client.handshakestr = handshake
if cmd == "Upgrade:":
print("Sending handshake:")
print(client.handshakestr)
print("End of Handshake")
client.send(client.handshakestr)
server = TelnetServer(port=6112, on_connect=client_connects, on_disconnect=client_disconnects)
while True:
process_clients()
server.poll()
似乎让我通过了最初的握手,但随后它立即下降。从输出来看,浏览器似乎期待进一步的东西,但我不知道是什么。对于客户端,我在从http://opiate.github.io/SimpleWebSocketServer/
下载的firefox 29.0上使用以下代码<!DOCTYPE html>
<meta charset="utf-8" />
<title>WebSocket Test</title>
<script language="javascript" type="text/javascript">
function init()
{
document.myform.url.value = "ws://localhost:8000/"
document.myform.inputtext.value = "Hello World!"
document.myform.disconnectButton.disabled = true;
}
function doConnect()
{
websocket = new WebSocket(document.myform.url.value);
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
}
function onOpen(evt)
{
writeToScreen("connectedn");
document.myform.connectButton.disabled = true;
document.myform.disconnectButton.disabled = false;
}
function onClose(evt)
{
writeToScreen("disconnectedn");
document.myform.connectButton.disabled = false;
document.myform.disconnectButton.disabled = true;
}
function onMessage(evt)
{
writeToScreen("response: " + evt.data + 'n');
}
function onError(evt)
{
writeToScreen('error: ' + evt.data + 'n');
websocket.close();
document.myform.connectButton.disabled = false;
document.myform.disconnectButton.disabled = true;
}
function doSend(message)
{
writeToScreen("sent: " + message + 'n');
websocket.send(message);
}
function writeToScreen(message)
{
document.myform.outputtext.value += message
document.myform.outputtext.scrollTop = document.myform.outputtext.scrollHeight;
}
window.addEventListener("load", init, false);
function sendText() {
doSend( document.myform.inputtext.value );
}
function clearText() {
document.myform.outputtext.value = "";
}
function doDisconnect() {
websocket.close();
}
</script>
<div id="output"></div>
<form name="myform">
<p>
<textarea name="outputtext" rows="20" cols="50"></textarea>
</p>
<p>
<textarea name="inputtext" cols="50"></textarea>
</p>
<p>
<textarea name="url" cols="50"></textarea>
</p>
<p>
<input type="button" name=sendButton value="Send" onClick="sendText();">
<input type="button" name=clearButton value="Clear" onClick="clearText();">
<input type="button" name=disconnectButton value="Disconnect" onClick="doDisconnect();">
<input type="button" name=connectButton value="Connect" onClick="doConnect();">
</p>
</form>
</html>
有人知道吗?1. 一个更容易的方法来使用websockets与我的Telnet服务器?2. 我在响应websocket连接的尝试有什么问题?3.我是否应该放弃并满足于使用带有网络连接的代理服务器?
Tornado有一个很好的兼容WebSocket处理程序。您可以使用它,或者在构建您的时将其用作参考。