python socketio 实现(极)简单聊天室

1、安装socketio服务端

# 官网介绍:https://python-socketio.readthedocs.io/en/latest/server.html
pip install python-socketio

2、服务端代码(socketio_server.py)

import logging
import socketio
from aiohttp import web
from urllib import parse
from bidict import bidict


async def chat_room(request):
    with open('./static/chat_room.html') as f:
        return web.Response(text=f.read(), content_type='text/html')


async def login(request):
    data = await request.json()
    user_name = data['user_name']
    if user_sid.get(user_name, None):
        return web.json_response({'code': 'fail'}, status=-1)
    else:
        return web.json_response({'code': 'success'}, status=200)


async def connect(sid, environ):
    query_params = environ['QUERY_STRING'].split('&')
    params = dict()
    for query_param in query_params:
        a, b = query_param.split('=')
        params[a] = parse.unquote(b)
    user_name = params['name']
    user_sid[user_name] = sid
    await sio.emit('reply', f'{user_name}连线成功!', namespace='/chat')


async def message(sid, data):
    # print("server received message!", data)
    await sio.emit('reply', f"{user_sid.inv[sid]}: {data}", namespace='/chat')


async def disconnect(sid):
    user_name = user_sid.inv[sid]
    del user_sid[user_name]
    await sio.emit('reply', f'{user_name}退出连线!', namespace='/chat')


if __name__ == '__main__':
    app = web.Application()
    # logging.basicConfig(level=logging.DEBUG)
    app.router.add_get('/chat_room', chat_room)
    app.router.add_routes([web.post('/login', login)])
    app.router.add_static('/static', 'static')

    sio = socketio.AsyncServer()
    sio.on('disconnect', disconnect, namespace='/chat')
    sio.on('chat message', message, namespace='/chat')
    sio.on('connect', connect, namespace='/chat')
    sio.attach(app)

    user_sid = bidict()
    web.run_app(app, host='localhost')

    # 聊天室页面:http://localhost:8080/chat_room
    # 如果修改ip地址需要修改chat_room.html中的第20行以及第61的localhost

3、聊天室页面(chat_room.html)

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>WebSocket Chat</title>
</head>

<body>
用户名:<input type="text" id="uname"/><br>
<input type="submit" value="登录" onclick="checkuser()"/>
<script src="static/socket.io-client-4.1.2/dist/socket.io.js"></script>
<script type="text/javascript">
        var socket;
        function get_in_room(name) {
            if (!window.WebSocket) {
                window.WebSocket = window.MozWebSocket;
            }
            if (window.WebSocket) {
                socket = io('http://localhost:8080/chat?name=' + name);
                socket.on('message', function (msg) {
                    var ta = document.getElementById('responseText');
                    ta.value = ta.value + '\n' + name + ': ' + event.data;
                });
                socket.on('reply', function (msg) {
                    var ta = document.getElementById('responseText');
                    ta.value = ta.value + '\n' + msg;
                    down();
                });
            } else {
                alert("你的瀏覽器不支援 WebSocket!");
            }
        }

        function check_login() {
            if (!window.WebSocket) {
                return;
            }
            if (typeof socket == "undefined") {
                alert('请先登录');
                return
            }
        }

        function send_message(message) {
            check_login();
            socket.emit('chat message', message);
            empty_input()
        }

        function enter_message(message) {
            if (event.keyCode == 13) {
                check_login();
                socket.emit('chat message', message);
                empty_input()
            }
        }
        function getValue(id) {
            return document.getElementById(id).value;
        }
        function checkuser() {
            var xhr = new XMLHttpRequest();
            //使用HTTP POST请求与服务器交互数据
            xhr.open("POST", "http://localhost:8080/login", true);
            //设置发送数据的请求格式
            xhr.setRequestHeader('content-type', 'application/json; charset=utf-8');
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    //根据服务器的响应内容格式处理响应结果
                    if (xhr.getResponseHeader('content-type') === 'application/json; charset=utf-8') {
                        var result = JSON.parse(xhr.responseText);
                        //根据返回结果判断验证码是否正确
                        if (result.code === 'fail') {
                            alert('名称已存在');
                            return;
                        } else {
                            console.log(1, xhr.responseText);
                            get_in_room(getValue('uname'));
                        }
                    }
                }
            }
            var sendData = { 'user_name': getValue('uname') };
            //将用户输入值序列化成字符串
            xhr.send(JSON.stringify(sendData));
        }
        function down() {
            var textarea = document.getElementById('responseText');
            textarea.scrollTop = textarea.scrollHeight;
        }

        function empty_input(){
            var m = document.getElementById('message');
            m.value = ''
        }



</script>
<form onsubmit="return false;">
    <h3>WebSocket 聊天室:</h3>
    <textarea id="responseText" style="width: 500px; height: 300px;"></textarea>
    <br>
    <input id="message" type="text" name="message" style="width: 300px" placeholder="在此输入聊天信息"
           onkeydown="enter_message(value)">
    <input type="button" value="发送信息" onclick="send_message(this.form.message.value)">
    <input type="button" onclick="javascript:document.getElementById('responseText').value=''" value="清空聊天记录">
</form>
<br>
<br>
</body>

</html>

这个html中需要socketio的客户端js代码

socketio js来源:https://github.com/socketio/socket.io-client/releases/tag/4.1.2

下载后文件目录结构如下

├── socketio_server.py
└── static
    ├── chat_room.html
    └── socket.io-client-4.1.2

4、运行

直接run socketio_server.py,然后打开http://localhost:8080/chat_room就可以进入聊天室。聊天前需要先填写用户名登录,无需密码,但用户名不允许重复;注意如果修改ip,同时需要修改html文件

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值