websocket----聊天室,推送等服务

websocket 是一种协议,和http 配合实用

http的特点是 链接后 客户端向服务端请求,服务端相应后断开链接,

因为http 有这个特点 所以 服务端不好主动向客户端发起请求

虽然有长连接的方法可以解决这个问题,但是性能开销太大,解决方案并不很好

所以就诞生了websocket

客户端与服务端链接以后,双方都可以主动发起请求,并在数据交互之后不会有任何一方自动断开链接

除非执行了断开链接的命令(客户端是关闭浏览器,或者一些关闭命令)

 

博主用的是django,  dwebsocket

作者地址:https://github.com/duanhongyi/dwebsocket

 

urls.py

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index),
    url(r'^index2/', views.index2),
    url(r'^echo$', views.echo),
    url(r'^echo_once/', views.echo_once),
]
路由

 

views.py

from django.shortcuts import render,HttpResponse,render
from dwebsocket import require_websocket
from dwebsocket.decorators import accept_websocket,require_websocket
import threading

@require_websocket
def echo_once(request):
    message = request.websocket.wait()
    request.websocket.send(message)



def index(req):
    return render(req,'index.html')

def index2(req):
    return render(req,'abc.html')



peo_l = []
@accept_websocket
def echo(request):
    if not request.is_websocket():#判断是不是websocket连接
        try:#如果是普通的http方法
            message = request.GET['message']
            return HttpResponse(message)
        except:
            return render(request,'index.html')
    else:
        lock=threading.RLock()
        lock.acquire()
        try:
            peo_l.append(request.websocket)
            for message in request.websocket:
                if not message:
                    break
                for webs in peo_l:
                    webs.send(message)#发送消息到客户端
        finally:
            peo_l.remove(request.websocket)
            lock.release()
视图

 

templates

<!DOCTYPE html>
<html>
<head>
    <title>django-websocket</title>
    <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script type="text/javascript">//<![CDATA[
    $(function () {
        $('#connect_websocket').click(function () {
            if (window.s) {
                window.s.close()
            }
            /*创建socket连接*/
            var socket = new WebSocket("ws://" + window.location.host + "/echo");
            socket.onopen = function () {
                console.log('WebSocket open');//成功连接上Websocket
            };
            socket.onmessage = function (e) {
                console.log('message: ' + e.data);//打印出服务端返回过来的数据
                $('#messagecontainer').prepend('<p>' + e.data + '</p>');
            };
            // Call onopen directly if socket is already open
            if (socket.readyState == WebSocket.OPEN) socket.onopen();
            window.s = socket;
        });
        $('#send_message').click(function () {
            //如果未连接到websocket
            if (!window.s) {
                alert("websocket未连接.");
            } else {
                window.s.send($('#message').val());//通过websocket发送数据
            }
        });
        $('#close_websocket').click(function () {
            if (window.s) {
                window.s.close();//关闭websocket
                console.log('websocket已关闭');
            }
        });
    });
    //]]></script>
</head>
<body>
<br>
<input type="text" id="message" value="Hello, World!"/>
<button type="button" id="connect_websocket">连接 websocket</button>
<button type="button" id="send_message">发送 message</button>
<button type="button" id="close_websocket">关闭 websocket</button>
<h1>Received Messages</h1>
<div id="messagecontainer">

</div>
</body>
</html>
模板

 

demo的效果是 打开2个以上 浏览器

从http://ip:port/index/ 中进去 

连接websocket后    发送message

假如 有 窗口A 和窗口B

都连接了 websocket后  

窗口A的input框  输入  "我是窗口A"

这时 窗口A 和窗口B 同时 显示   "我是窗口A"

 

这就是 最终想要的效果 

但是如果 再打开窗口C   没有连接socket 是  不会受到任何信息的

 

posted @ 2018-07-19 17:28  昂达达  阅读(470)  评论(0编辑  收藏  举报