一个基本的websocket通信服务器
WsComSrv的Python项目详细描述
##服务器
允许WebSocket客户端之间通信的套接字服务器
在他们之间发送命令。
服务器可以通过socketserver = SockerServer()
默认情况下,服务器使用127.0.0.1(通常等同于“localhost”)作为主机和端口8888。
可以使用相应的参数将其更改为任何其他主机/端口:socketserver = SockerServer(port='localhost',port=8888)
如果服务器无法绑定到主机:端口对,则会抛出一个oserror。 这可用于连接到第一个空闲端口
SOCKETPORT=8888
notconnected = True
socketserver = None
while notconnected:
try:
socketserver = SockerServer(port=SOCKETPORT)
notconnected = False
except:
SOCKETPORT += 1
端口打开后,可以通过调用:socketserver.run_forever()
默认情况下,服务器向任何连接的客户端请求标识,并发送一个可用于时间同步的时间戳(请参见下文)
##客户
该软件包还附带了一个客户端。
调用客户端使用:wsc = WebSocketClient("name",host="ws://127.0.0.1:8888")
名称应该是唯一的,并且必须根据套接字服务器更改主机。
如果提供了主机(不是无主机),则客户端将立即连接到服务器。如果没有提供主机或自动连接设置为false
必须通过调用建立连接:wsc.connect_to_socket("hostadress")
当连接、断开连接或发生错误时,客户端可以调用函数:
添加函数调用:wsc.add_on_open("name", func[,overwrite=False])#run func on connecting
如果nesessary和overwrite=false(默认值)保护已设置的函数不被相同的名称覆盖,则该名称用作删除函数的引用。
没有参数传递给函数。断开连接(add_on_close)和错误(add_on_error)功能也是如此。
默认情况下,客户端在出错或关闭时重新连接。要关闭此选项,请将reconnect属性设置为false
以同样的方式,可以将on消息分配给客户机。在这种情况下,传递的函数会将按摩调整为参数。
最初,内部消息验证器作为on message函数添加,该函数根据默认消息模板验证消息:
{
"type": "messagetype",
"data": {},
"from": sendername,
"target": messagetarget,
}
默认情况下,如果消息类型为“cmd”,则消息将威胁为commandmessage并经过验证。 命令消息必须具有数据结构:
{
"cmd": "commandname",
"args": [],
"kwargs": {}
}
最初注册了两个命令:
- “identify”:响应服务器的identify请求并向socketclient.name注册
- “set_time”:将socketclient.time设置为可用于时间同步的给定数据。
其他命令可以通过以下方式注册:wsc.add_cmd_function('name',func[,overwrite=False])
示例:
import time
import logging
import random
import threading
from websocket_communication_server.messagetemplates import commandmessage
from websocket_communication_server.socketclient import WebSocketClient
from websocket_communication_server.socketserver import SockerServer, SOCKETPORT
class Testclass:
def __init__(self, host, name):
self.runime = 0
self.name = name
self.wsc = WebSocketClient(name, host=host)
self.wsc.add_cmd_function("pass_ball", self.pass_ball) # registers own pass_ball method to be called when reciving the pass_ball command
self.pingpong = "ping" if "1" in name else "pong"
self.opponent = "Player2" if "1" in name else "Player1"
def pass_ball(self, catch=None): #methods called by the message validator should have default attributes to be valid against "TypeError: pass_ball() missing 1 required positional argument: 'catch'"
if catch is None:
print("End of the game because the ball went missing somewhere")
return
print(self.pingpong) # prints ping or pong
if not catch:
print("Damn!") # dont like losing the ball
time.sleep(1) # delay in game because it would be way to fast without, maybe the flytime of the ball :)
self.wsc.write_to_socket(
commandmessage(
cmd="pass_ball", # the command to call at the reciver
sender=self.name, # sender of the command
target=self.opponent, # reciver
catch=random.random() < 0.8, # 80% ball catch
)
)
if __name__ == "__main__":
# connects to the firsts free port
notconnected = True
socketserver = None
while notconnected:
try:
socketserver = SockerServer(port=SOCKETPORT) # binds to 127.0.0.1:8888++
notconnected = False
except:
SOCKETPORT += 1
threading.Thread(
target=socketserver.run_forever
).start() # runs server forever in background
test1 = Testclass(host=socketserver.ws_adress, name="Player1") # create player 1
test2 = Testclass(host=socketserver.ws_adress, name="Player2") # create player 2
time.sleep(1) # gives the players enought timw to identify
test1.pass_ball(True) # throw the first ball
while 1:
time.sleep(1) # play forever
输出:
发出砰的声响
乒乓球
发出砰的声响
乒乓球
发出砰的声响
乒乓球
该死!
发出砰的声响
该死!
乒乓球
发出砰的声响
乒乓球
发出砰的声响
乒乓球
发出砰的声响
乒乓球
ping