我创建了一个程序,作为浏览器和硬件之间的代理。浏览器以websocket的身份启动连接。然后,程序使用初始请求中指定的端口启动TCP服务器。一旦外部设备与TCP服务器建立连接,它就可以将数据发送到浏览器。代码示例到目前为止,但我还需要程序关闭TCP服务器和所有连接,如果任何连接关闭。另一个websocket请求应该再次启动该过程。
我似乎没有正确停止服务器/ websocket,因为系统将不再允许来自浏览器的websocket连接(连接被拒绝)。但是,所有其他处理程序仍将在http服务器上响应。
import aiohttp
from aiohttp import web
import asyncio
def TCPServerFactory(conns):
def _f(*args,**kwargs):
return TCPServer(conns,*args,**kwargs)
return _f
async def sendWS(conn,data):
await conn.send_str(data)
class TCPServer(asyncio.Protocol):
def __init__(self,conns,*args,**kwargs):
self.conns=conns
super().__init__(*args,**kwargs)
def connection_made(self,transport):
self.transport=transport
self.conns['tcp']=transport
def data_received(self,data):
asyncio.ensure_future(sendWS(self.conns['ws'],data.decode()))
def connection_lost(self,exc):
self.conns['ws'].close()
async def sendTCP(conn,data):
await conn.write(data)
async def wsHandler(request):
ws=web.WebSocketResponse()
await ws.prepare(request)
#Setup TCP server
loop=asyncio.get_event_loop()
conns={'ws':ws,'tcp':None}
try:
serv=await loop.create_server(TCPServerFactory(conns),'127.0.0.1',8000)
except:
await ws.close()
return ws
conns['tcpServ']=serv
async for msg in ws:
if msg.type==aiohttp.WSMsgType.TEXT:
if msg.data:
try:
conns['tcp'].write(bytes(msg.data,'utf-8'))
except:
break
elif msg.type==aiohttp.WSMsgType.CLOSING:
break
else:
break
try:
conns['tcp'].close()
except:
pass
serv.close()
await serv.wait_closed()
await ws.close()
return ws
async def handleTCP(request):
return web.Response(text='TCP worked',headers={'Access-Control-Allow-Origin':'*'})
async def handleHome(request):
return web.FileResponse(r'c:\workspace\lserver\lserver\test.html')
class HttpServer:
def start(self):
asyncio.set_event_loop(asyncio.ProactorEventLoop())
self.loop=asyncio.get_event_loop()
self.app=web.Application()
self.app.router.add_get('/tcp',wsHandler)
self.app.router.add_get('/',handleHome)
web.run_app(self.app,host='0.0.0.0',port=8080)
self.loop.close()
http=HttpServer()
http.start()