您的位置:首页 > 汽车 > 时评 > 凡科轻站小程序制作平台_展览展示搭建设计_沈阳黄页88企业名录_厦门seo网站推广优化

凡科轻站小程序制作平台_展览展示搭建设计_沈阳黄页88企业名录_厦门seo网站推广优化

2025/2/12 16:05:39 来源:https://blog.csdn.net/weixin_44689630/article/details/144728936  浏览:    关键词:凡科轻站小程序制作平台_展览展示搭建设计_沈阳黄页88企业名录_厦门seo网站推广优化
凡科轻站小程序制作平台_展览展示搭建设计_沈阳黄页88企业名录_厦门seo网站推广优化

文章目录

  • 即时通讯
    • 1.类型
    • 2.需求场景
    • 3.传统的推送实现
    • 4.websocket
    • 5.websocket优点
    • 6.websocket库Socket.IO
      • 1.安装
      • 2.创建服务
      • 3.常见方法
    • 7.Django+channel
      • 1.安装
      • 2.配置

即时通讯

定义: 即时通讯(Instant Messaging)

1.类型

  • 在线push适用于web页面和APP

    • 使用websocket
    • 使用Socket.IO
    • 自己封装socket
  • 离线push:APP

    • ios:APNs
    • andorid:FCM/第三方服务(网易云信/融云/环信/LeanCloud)

2.需求场景

  • 即时聊天
  • 用户A关注了用户B,系统需要向用户B推送提示消息
  • 用户下了订单,需要在运营管理后台向运营人员推送新订单通知

3.传统的推送实现

HTTP/1.x 不支持服务器主动推送,HTTP/2支持服务器主动推送,但HTTP/2 还未全面实施

  • 轮询:

    • 定义:浏览器每隔一段时间就向浏览器发送http请求,不论是否有数据更新都直接响应,
    • 缺点:效率低下,浪费资源
  • 长轮训(基于长连接Comet):

    • 定义:服务端收到客户端的请求不会直接响应,而是先将这个请求挂起来,然后判断服务端数据是否有更新,如果有更新,则响应,如果没有数据,则达到一定时间限制才返回
    • 缺点:依然需要反复发出请求效率低下,浪费资源

4.websocket

WebSocket协议定义:

  • 是基于html5(HyperText Markup Language)定义的协议

  • 单个TCP连接上进行全双工通信的协议

  • Websocket 通过 HTTP/1.1 协议的101状态码进行握手

  • ws或wss的统一资源标志符

    ws://example.com/wsapi
    wss://secure.example.com/
    
  • 端口:80/443

  • 报文

    # 客户端
    GET / HTTP/1.1
    Upgrade: websocket   # 必须设置Websocket,表示希望升级到Websocket协议
    Connection: Upgrade  # 客户端希望连接升级
    Host: example.com   
    Origin: http://example.com
    # Sec-WebSocket-Key与magic_string进行hmac1加密,再进行base64加密
    Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ== # 随机的字符串
    Sec-WebSocket-Version: 13# 服务端
    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s=
    Sec-WebSocket-Location: ws://example.com/
    

5.websocket优点

  • 较少的控制开销
  • 更强的实时性
  • 保持连接状态
  • 可以支持扩展
  • 更好压缩效果
  • 没有的压缩效果
  • 没有同源限制
  • 可以发送文本

6.websocket库Socket.IO

1.安装

pip install python-socketio

2.创建服务

方式一:协程方式访问

import eventleteventlet.monkey_patch()import socketio
import eventlet.wsgisio = socketio.Server(async_mode='eventlet')
app = socketio.Middleware(sio)
eventlet.wsgi.server(eventlet.listen(('', 8000)), app)

为什么不使用多进程或多线程

  • 受限于服务能性能有限创建的进程数和线程数,导致并发连接客户端不会很高,

3.常见方法

  • @sio.on(‘connect’),connect 为特殊事件,当客户端连接后自动执行

    @sio.on('connect')
    def on_connect(sid, environ):"""与客户端建立好连接后被执行:param sid: string sid是socketio为当前连接客户端生成的识别id:param environ: dict 在连接握手时客户端发送的握手数据(HTTP报文解析之后的字典)"""pass
    
  • @sio.on(‘disconnect’),disconnect 为特殊事件,当客户端断开连接后自动执行

    @sio.on('disconnect')
    def on_disconnect(sid):"""与客户端断开连接后被执行:param sid: string sid是断开连接的客户端id"""pass
    
  • @sio.on(‘自定义事件’) ,connect,disconnect与自定义事件处理方法的函数传入参数不同

    # 以字符串的形式表示一个自定义事件,事件的定义由前后端约定
    @sio.on('my custom event')  
    def my_custom_event(sid, data):"""自定义事件消息的处理方法:param sid: string sid是发送此事件消息的客户端id:param data: data是客户端发送的消息数据"""pass
    
  • sio.emit(),:发送事件消息

    #群发特定事件消息
    sio.emit('my event', {'data': 'foobar'})
    #给指定用户特定事件消息发送
    sio.emit('my event', {'data': 'foobar'}, room=user_sid)
    #群发所有人
    sio.send({'data': 'foobar'})
    # 群发给指定房间的人
    sio.send({'data': 'foobar'}, room=user_sid)
  • sio.rooms(sid):查询sid客户端所在的所有房间

  • sio.enter_room(sid, room_name):将连接的客户端添加到一个room

  • sio.leave_room(sid, room_name):将客户端从一个room中移除

7.Django+channel

1.安装

pip install channels==4.2.0
pip install daphne==4.1.2

2.配置

asgi.py

import osfrom django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouterfrom app1 import routingsos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoProject.settings')application = ProtocolTypeRouter({'http': get_asgi_application(),  # 支持http请求'websocket': URLRouter(routings.websocket_urlpatterns),  # 支持websocket请求
})

settings.py

INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','daphne',  # 添加daphne'django.contrib.staticfiles','corsheaders','channels',# 添加channels'app1']
WSGI_APPLICATION = 'djangoProject.wsgi.application'
ASGI_APPLICATION = "djangoProject.asgi.application"

app1/urls.py

from django.contrib import admin
from django.urls import path
from app1.views import chaturlpatterns = [path('admin/', admin.site.urls),path("chatone", chat)
]

app1/views.py

from django.shortcuts import renderdef chat(request):return render(request, "chatting.html")

app1/routings.py

from django.urls import re_path
from app1 import consumers as consm1websocket_urlpatterns = [re_path(r'room/', consm1.ChatConsumer.as_asgi())
]

app1/consumers.py

from channels.exceptions import StopConsumer
from channels.generic.websocket import WebsocketConsumerclass ChatConsumer(WebsocketConsumer):def websocket_connect(self, message):"""客户端向服务端发送websocket连接的请求时自动触发。"""print("1 > 客户端和服务端开始建立连接")self.accept()def websocket_receive(self, message):"""客户端基于websocket向服务端发送数据时,自动触发接收消息。"""print(f"2 > 服务端接收客户端的消息, message is {message}")recv_data = message["text"]if recv_data == "exit":  # 服务端主动关闭websocket连接时,前端会执行对应的 oncloseself.close()# raise StopConsumer()    # raise主动抛异常后,websocket_disconnect 就不在执行了,多用于`只处理服务端向客户端断开`的场景returnsend_data = f"服务端主动推送消息:{recv_data}"self.send(text_data=send_data)def websocket_disconnect(self, message):"""客户端与服务端断开websocket连接时自动触发(不管是客户端向服务端断开还是服务端向客户端断开都会执行)"""print("3 > 客户端和服务端断开连接")self.close()raise StopConsumer()

chatting.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>.message {height: 300px;border: 1px solid #dddddd;width: 100%;}</style>
</head>
<body>
<div class="message" id="message"></div>
<div><input type="text" placeholder="请输入聊天内容:" id="txt"><input type="button" value="点击发送" onclick="sendMessage()"><input type="button" value="关闭连接" onclick="closeConn()">
</div><script>// 实例化websocket对象,并客户端主动以websocket方式连接服务端wbsocket = new WebSocket("ws://127.0.0.1:1010/room/123/");// 创建好websocket连接成功后自动触发(服务端执行self.accept()后)wbsocket.onopen = function (event) {var tag = document.createElement("div");tag.innerText = '[连接成功!]';document.getElementById("message").appendChild(tag);};// 创建连接失败后自动触发wbsocket.onerror = function (event) {var tag = document.createElement("div");tag.innerText = '[连接失败!]';document.getElementById("message").appendChild(tag);};// 当websocket接收到服务器发来的消息时会自动触发wbsocket.onmessage = function (event) {var tag = document.createElement("div");tag.innerText = event.data;document.getElementById("message").appendChild(tag);};// 当服务端主动断开客户端时自动触发(服务端执行self.close()后)wbsocket.onclose = function (event) {var tag = document.createElement("div");tag.innerText = '[连接已断开!]';document.getElementById("message").appendChild(tag);};// 页面上客户端点击向服务端"关闭连接"时触发function closeConn() {wbsocket.close();       // 客户端主动断开连接,服务端会执行 websocket_disconnect()var tag = document.createElement("div");tag.innerText = '[连接已断开啦!]';document.getElementById("message").appendChild(tag);}// 页面上客户端点击向服务端"发送消息"时触发function sendMessage() {var info = document.getElementById("txt");wbsocket.send(info.value);   // 客户端给服务端发数据}</script></body>
</html>

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com