python websocket 聊天服务器
博客专区 > james_lz 的博客 > 博客详情
python websocket 聊天服务器
james_lz 发表于8个月前
python websocket 聊天服务器
  • 发表于 8个月前
  • 阅读 56
  • 收藏 0
  • 点赞 0
  • 评论 3

腾讯云 新注册用户 域名抢购1元起>>>   

摘要: h5 的聊天服务websocket非常实用 曾经写过Java的 现在记录一下Python的websocket服务

 前提:

安装

pip install -U channels

add channels to your INSTALLED_APPS setting

服务端:consumers.py


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import datetime
import json

from channels import Group
from channels.auth import channel_session_user_from_http, channel_session_user


@channel_session_user_from_http
def ws_connect(message, game, room_id):
    # Add to the chat group
    Group(game).add(message.reply_channel)
    # Accept the connection
    message.reply_channel.send({"accept": True})


@channel_session_user
def ws_message(message, game, room_id):
    user = message.user
    if not user.id:
        data = {'stream': 'unauthorized', 'payload': {}}
        Group(game).send({"text": json.dumps(data)}, immediately=True)
        return

    data = {
        'stream': 'test',
        'payload': {
            'id': user.id,
            'username': user.username,
        }
    }
    Group(game).send({"text": json.dumps(data)}, immediately=True)


@channel_session_user
def ws_disconnect(message, game, room_id):
    Group(game).discard(message.reply_channel)

路由文件:routing.py

fromchannels.routing import route
from myapp.consumers import ws_add, ws_message, ws_disconnect
channel_routing= [
    route("websocket.connect",ws_add,path=r"^/(?P<game>[a-zA-Z]+)/(?P<room_id>[0-9]+)/$"),
    route("websocket.receive",ws_message,path=r"^/(?P<game>[a-zA-Z]+)/(?P<room_id>[0-9]+)/$"),
   route("websocket.disconnect", ws_disconnect,path=r"^/(?P<game>[a-zA-Z]+)/(?P<room_id>[0-9]+)/$"),
]

配置文件:setting.py

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "asgiref.inmemory.ChannelLayer",
        "ROUTING": "common.routing.channel_routing",
    },
}

它将channel数据存储在内存中的一个字典里,所以不能跨进程。当部署时还是要换成Redis后端asgi_redis等。

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "asgi_redis.RedisChannelLayer",
        "CONFIG": {
            "hosts": [("localhost", 6379)],
        },
        "ROUTING": "myproject.routing.channel_routing",
    },
}

因为Channles是分布式系统,默认它按workers从队列中获得的顺序处理消息。很可能interface server发出非常近的connect和receive消息,connect还未被处理完,receive就被另一个worker处理。

        Channels的解决方法是enforce_ordering装饰器。所有websocket消息都包含一个order键,这个装饰器用这个键确保message按顺序处理。有两个模式:

        Slightordering:connect先处理,其他无序。

        Strictordering:所有都按序。

 

参考:http://blog.csdn.net/linshiyx/article/details/51680418

         http://blog.csdn.net/zhu_free/article/details/48137375

        http://www.toutiao.com/i6396086415800664577/

 

      https://github.com/jacobian/channels-example

标签: Python WebSocket
共有 人打赏支持
粉丝 10
博文 140
码字总数 48432
评论 (3)
老农民28
我觉得这种东西自己开发太麻烦了,就别自己捣鼓了,找个第三方,方便,GoEasy就挺不错的,我昨天试了一下,代码简洁易懂,几分钟我就洗了一个自己的实时推送功能;官网: http://goeasy.io/
james_lz

引用来自“老农民28”的评论

我觉得这种东西自己开发太麻烦了,就别自己捣鼓了,找个第三方,方便,GoEasy就挺不错的,我昨天试了一下,代码简洁易懂,几分钟我就洗了一个自己的实时推送功能;官网: http://goeasy.io/
嗯 多谢建议 我看了一下 确实更简单 在浏览器的兼容问题上非常强大:thumbsup:
wahahachuang4

引用来自“老农民28”的评论

我觉得这种东西自己开发太麻烦了,就别自己捣鼓了,找个第三方,方便,GoEasy就挺不错的,我昨天试了一下,代码简洁易懂,几分钟我就洗了一个自己的实时推送功能;官网: http://goeasy.io/

引用来自“jamesamy”的评论

嗯 多谢建议 我看了一下 确实更简单 在浏览器的兼容问题上非常强大:thumbsup:
:laughing::blush::blush:
×
james_lz
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: