运行多个websocket连接

时间:2019-01-04 08:15:48

标签: python websocket

这是我的代码段

import asyncio
import websockets

async def get_cells(websocket, path):
    async for message in websocket:
        ... some code

async def get_shaded_area(websocket, path):
    async for message in websocket:
        ... #some code


asyncio.get_event_loop().run_until_complete(
    websockets.serve(get_cells, 'localhost', 8765))

asyncio.get_event_loop().run_until_complete(
    websockets.serve(get_shaded_area, 'localhost/shade-area', 8765))

asyncio.get_event_loop().run_forever()

它仅以get_cells开头,因此对于get_event_loop只有一个get_cells可以正常工作。

由于我想建立一个以上的ws连接,因为每个处理不同的数据并在添加后的第二个get_shaded_area中返回不同的结果,都会引发此错误:

(pixelart) sam@sam-Lenovo-G51-35:~/code/pixelart$ python path.py
Traceback (most recent call last):
File "path.py", line 144, in <module>
    websockets.serve(get_shaded_area, 'localhost/shade-area', 8765))
File "/usr/lib/python3.6/asyncio/base_events.py", line 473, in run_until_complete
    return future.result()
File "/usr/lib/python3.6/asyncio/tasks.py", line 537, in _wrap_awaitable
    return (yield from awaitable.__await__())
File "/home/sam/code/envs/pixelart/lib/python3.6/site-packages/websockets/py35/server.py", line 13, in __await_impl__
    server = await self._creating_server
File "/usr/lib/python3.6/asyncio/base_events.py", line 1019, in create_server
    infos = yield from tasks.gather(*fs, loop=self)
File "/usr/lib/python3.6/asyncio/base_events.py", line 968, in _create_server_getaddrinfo
    flags=flags, loop=self)
File "/usr/lib/python3.6/concurrent/futures/thread.py", line 56, in run
    result = self.fn(*self.args, **self.kwargs)
File "/usr/lib/python3.6/socket.py", line 745, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -2] Name or service not known

2 个答案:

答案 0 :(得分:0)

您不能在同一对host:port对上运行多台服务器,而应该处理传递的路径-该路径是端点,客户端r在WS连接期间请求。

正确的模式是创建一个“路由器”,它将为您完成工作。 Windows Documentation代码(简单的代码即可显示我的意思):

import asyncio
import websockets


async def get_shaded_area(message):
  print('shade-area:' + message)


async def get_cells(messzage):
  print('Cells area:' + messzage)


async def router(websocket, path):
  async for message in websocket:
    if path == "/shade-area":
      await get_shaded_area(message)
    else:
      await get_cells(message)


def main():
  asyncio.get_event_loop().run_until_complete(websockets.serve(router, '127.0.0.1', 8765))
  asyncio.get_event_loop().run_forever()


if __name__ == '__main__':
  main()

答案 1 :(得分:0)

我将这个软件包的问题发布到了github仓库,并得到了一个简单的解决方案。

import io.circe.Decoder

val decoder = Decoder.decodeMap(KeyDecoder.decodeKeyString, Decoder.decodeString)

val result = for {
  json <- parse(rawJson).toTry
  map <- decoder.decodeJson(json).toTry
} yield map

val map = result.get
println(map)