python使用websockets库

python使用websockets库

serve:在server端使用,等待客户端的连接。如果连接成功,返回一个websocket。

connect: 在client端使用,用于建立连接。

send:发送数据

recv:接收数据

close:关闭连接

服务端

#!/usr/bin/python3
# 主要功能:创建1个基本的websocket server, 符合asyncio 开发要求
import asyncio
import websockets
from datetime import datetime


async def handler(websocket):
    data = await websocket.recv()
    reply = f"Data received as \"{data}\".  time: {datetime.now()}"
    print(reply)
    await websocket.send(reply)
    print("Send reply")


async def main():
    async with websockets.serve(handler, "localhost", 9999):
        await asyncio.Future()  # run forever

if __name__ == "__main__":
    asyncio.run(main())



客户端

import asyncio
import websockets
import time


async def ws_client(url):
    for i in range(1, 40):
        async with websockets.connect(url) as websocket:
            await websocket.send("Hello, I am PyPy.")
            response = await websocket.recv()
        print(response)
        time.sleep(1)

asyncio.run(ws_client('ws://localhost:9999'))




服务端

import asyncio
import websockets

IP_ADDR = "127.0.0.1"
IP_PORT = "9090"


# 握手,通过接收Hi,发送"success"来进行双方的握手。
async def serverHands(websocket):
    while True:
        recv_text = await websocket.recv()
        print("recv_text=" + recv_text)
        if recv_text == "Hi":
            print("connected success")
            await websocket.send("success")
            return True
        else:
            await websocket.send("connected fail")


# 接收从客户端发来的消息并处理,再返给客户端success
async def serverRecv(websocket):
    while True:
        recv_text = await websocket.recv()
        print("recv:", recv_text)
        await websocket.send("success,get mess:"+ recv_text)


# 握手并且接收数据
async def serverRun(websocket, path):
    print(path)
    await serverHands(websocket)
    await serverRecv(websocket)


# main function
if __name__ == '__main__':
    print("======server======")
    server = websockets.serve(serverRun, IP_ADDR, IP_PORT)
    asyncio.get_event_loop().run_until_complete(server)
    asyncio.get_event_loop().run_forever()

客户端

import asyncio
import websockets

IP_ADDR = "127.0.0.1"
IP_PORT = "9090"



async def clientHands(websocket):
    while True:
        # 通过发送hello握手
        await websocket.send("Hi")
        response_str = await websocket.recv()
        # 接收"success"来进行双方的握手
        if "success" in response_str:
            print("握手成功")
            return True


# 向服务器端发送消息
async def clientSend(websocket):
    while True:
        input_text = input("input text: ")
        if input_text == "exit":
            print(f'"exit", bye!')
            await websocket.close(reason="exit")
            return False
        await websocket.send(input_text)
        recv_text = await websocket.recv()
        print(f"{recv_text}")


# 进行websocket连接
async def clientRun():
    ipaddress = IP_ADDR + ":" + IP_PORT
    async with websockets.connect("ws://" + ipaddress) as websocket:
        await clientHands(websocket)
        await clientSend(websocket)


# main function
if __name__ == '__main__':
    print("======client======")
    asyncio.get_event_loop().run_until_complete(clientRun())


在这里插入图片描述

服务端

# -*- coding:utf8 -*-

import json
import socket
import asyncio
import logging
import websockets
import multiprocessing

IP = '127.0.0.1'
PORT_CHAT = 9090

USERS ={}

#提供聊天的后台
async def ServerWs(websocket,path):
    logging.basicConfig(format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s',
                        filename="chat.log",
                        level=logging.INFO)
    # 握手
    await websocket.send(json.dumps({"type": "handshake"}))
    async for message in websocket:
        data = json.loads(message)
        message = ''
        # 用户发信息
        if data["type"] == 'send':
            name = '404'
            for k, v in USERS.items():
                if v == websocket:
                    name = k
            data["from"] = name
            if len(USERS) != 0:  # asyncio.wait doesn't accept an empty list
                message = json.dumps(
                    {"type": "user", "content": data["content"], "from": name})
        # 用户注册
        elif data["type"] == 'register':
            try:
                USERS[data["uuid"]] = websocket
                if len(USERS) != 0:  # asyncio.wait doesn't accept an empty list
                    message = json.dumps(
                        {"type": "login", "content": data["content"], "user_list": list(USERS.keys())})
            except Exception as exp:
                print(exp)
        # 用户注销
        elif data["type"] == 'unregister':
            del USERS[data["uuid"]]
            if len(USERS) != 0:  # asyncio.wait doesn't accept an empty list
                message = json.dumps(
                    {"type": "logout", "content": data["content"], "user_list": list(USERS.keys())})
        #打印日志
        logging.info(data)
        # 群发
        await asyncio.wait([user.send(message) for user in USERS.values()])


def server_run():
    print("server")
    start_server = websockets.serve(ServerWs, '0.0.0.0', PORT_CHAT)
    asyncio.get_event_loop().run_until_complete(start_server)
    asyncio.get_event_loop().run_forever()


if __name__ == "__main__":
    from multiprocessing import Process
    multiprocessing.freeze_support()
    server = Process(target=server_run, daemon=False)
    server.start()


服务端


import asyncio
import websockets
import time
import json
import threading
# 功能模块
class OutputHandler():
    async def run(self,message,send_ms,websocket):
        # 用户发信息
        await send_ms(message, websocket)
        # 单发消息
        # await send_ms(message, websocket)
        # 群发消息
        #await s('hi起来')


# 存储所有的客户端
Clients = {}

# 服务端
class WS_Server():
    def __init__(self):
        self.ip = "127.0.0.1"
        self.port = 9090

    # 回调函数(发消息给客户端)
    async def callback_send(self, msg, websocket=None):
        await self.sendMsg(msg, websocket)

    # 发送消息
    async def sendMsg(self, msg, websocket):
        print('sendMsg:', msg)
        # websocket不为空,单发,为空,群发消息
        if websocket != None:
            await websocket.send(msg)
        else:
            # 群发消息
            await self.broadcastMsg(msg)
        # 避免被卡线程
        await asyncio.sleep(0.2)

    # 群发消息
    async def broadcastMsg(self, msg):
        for user in Clients:
            await user.send(msg)


    # 针对不同的信息进行请求,可以考虑json文本
    async def runCaseX(self,jsonMsg,websocket):
        print('runCase')
        op = OutputHandler()
        # 参数:消息、方法、socket
        await op.run(jsonMsg,self.callback_send,websocket)

    # 连接一个客户端,起一个循环监听
    async def echo(self,websocket, path):
        # 添加到客户端列表
        # Clients.append(websocket)
        # 握手
        await websocket.send(json.dumps({"type": "handshake"}))
        # 循环监听
        while True:
            # 接受信息
            try:
                # 接受文本
                recv_text = await websocket.recv()
                message = "Get message: {}".format(recv_text)
                # 返回客户端信息
                await websocket.send(message)
                # 转json
                data = json.loads(recv_text)

                # 用户发信息
                if data["type"] == 'send':
                    name = '404'
                    for k, v in Clients.items():
                        if v == websocket:
                            name = k
                    data["from"] = name
                    if len(Clients) != 0:  # asyncio.wait doesn't accept an empty list
                        message = json.dumps({"type": "send", "content": data["content"], "from": name})
                        await self.runCaseX(jsonMsg=message, websocket=websocket)

                # 用户注册
                elif data["type"] == 'register':
                    try:
                        Clients[data["uuid"]] = websocket
                        if len(Clients) != 0:  # asyncio.wait doesn't accept an empty list
                            message = json.dumps({"type": "register", "content": data["content"], "user_list": list(Clients.keys())})
                            await self.runCaseX(jsonMsg=message, websocket=websocket)
                    except Exception as exp:
                        print(exp)

                # 用户注销
                elif data["type"] == 'unregister':
                    del Clients[data["uuid"]]

                # 对message进行解析,跳进不同功能区
                # await self.runCaseX(jsonMsg=data,websocket=websocket)
            # 链接断开
            except websockets.ConnectionClosed:
                print("ConnectionClosed...", path)
                # del Clients
                break
            # 无效状态
            except websockets.InvalidState:
                print("InvalidState...")
                # del Clients
                break
            # 报错
            except Exception as e:
                print("ws连接报错",e)
                # del Clients
                break



    # 启动服务器
    async def runServer(self):
        async with websockets.serve(self.echo, self.ip, self.port):
            await asyncio.Future()  # run forever

	# 多协程模式,防止阻塞主线程无法做其他事情
    def WebSocketServer(self):
        asyncio.run(self.runServer())

    # 多线程启动
    def startServer(self):
        # 多线程启动,否则会堵塞
        thread = threading.Thread(target=self.WebSocketServer)
        thread.start()
        # thread.join()


if __name__=='__main__':
    print("server")
    s = WS_Server()
    s.startServer()


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值