>  기사  >  백엔드 개발  >  Django에서 Websocket을 사용하는 방법에 대한 자세한 설명

Django에서 Websocket을 사용하는 방법에 대한 자세한 설명

高洛峰
高洛峰원래의
2017-03-24 16:41:593611검색

1. 웹소켓 소개

인터넷이 발전하면서 전통적인 HTTP 프로토콜은 점점 더 복잡해지는 웹 애플리케이션의 요구를 충족하기가 어려워졌습니다. 최근에는 HTML5의 탄생과 함께 브라우저와 서버 간의 전이중 통신을 구현하고, 브라우저와 서버 간의 통신 기능을 확장하며, 서버가 적극적으로 데이터를 클라이언트에 전송할 수 있도록 하는 WebSocket 프로토콜이 제안되었습니다. 고객.
우리는 전통적인 HTTP 프로토콜이 상태 비저장이라는 것을 알고 있습니다. 각 요청(요청)은 클라이언트(예: 브라우저)에 의해 적극적으로 시작되어야 하며, 서버는 처리 후 응답 결과를 반환하기가 어렵습니다. 요청 클라이언트는 데이터를 보냅니다. 클라이언트가 활성 당사자이고 서버가 수동 당사자인 이 전통적인 웹 모델은 정보가 자주 변경되지 않는 웹 애플리케이션에 문제를 덜 일으키지만 실시간 정보와 관련된 웹 애플리케이션에는 문제를 일으킵니다. 인스턴트 메시징, 실시간 데이터, 구독 푸시 및 기타 기능을 갖춘 애플리케이션과 같은 큰 불편이 있습니다. WebSocket 사양이 제안되기 전에 개발자는 폴링 및 Comet 기술과 같은 실시간 기능을 구현하기 위해 종종 절충 솔루션을 사용했습니다. 사실 후자는 본질적으로 일종의 여론조사인데 개선된 것이다.
폴링은 실시간 웹 애플리케이션 구현을 위한 독창적인 솔루션입니다. 폴링 기술을 사용하려면 클라이언트가 설정된 간격으로 주기적으로 서버에 요청을 보내고 새로운 데이터 변경 사항이 있는지 자주 쿼리해야 합니다. 분명히 이 접근 방식은 불필요한 요청이 너무 많아 트래픽과 서버 리소스가 낭비되는 결과를 낳습니다.
Comet 기술은 롱폴링 기술과 스트리밍 기술로 나눌 수 있습니다. 긴 폴링은 위의 폴링 기술을 향상시키고 불필요한 요청을 줄입니다. 특정 데이터에 대한 만료 시간을 설정하고 데이터가 만료된 경우에만 서버에 요청을 보냅니다. 이 메커니즘은 데이터 변경이 특별히 자주 발생하지 않는 상황에 적합합니다. 스트리밍 기술은 일반적으로 클라이언트가 숨겨진 창을 사용하여 서버와 긴 HTTP 연결을 설정하는 것을 의미합니다. 이 경우 서버는 이 긴 HTTP 연결을 유지하기 위해 연결 상태를 지속적으로 업데이트합니다. 클라이언트로 전송되는 스트리밍 기술은 대규모 동시성 환경에서 서버의 성능을 테스트할 수 있습니다.
이 두 기술은 요청-응답 모델을 기반으로 하며, 둘 다 진정한 의미의 실시간 기술이 아니며, 각각의 요청과 응답은 동일한 헤더 정보에 대해 일정량의 트래픽을 낭비하고 개발 복잡성이 높습니다. 또한 더 큽니다.
HTML5에서 WebSocket이 출시되면서 웹에서의 실시간 통신이 본격적으로 구현되어 B/S 모드도 C/S 모드의 실시간 통신 기능을 갖게 되었습니다. WebSocket의 작업 흐름은 다음과 같습니다. 브라우저는 JavaScript를 통해 WebSocket 연결을 설정하라는 요청을 서버에 보냅니다. WebSocket 연결이 성공적으로 설정된 후 클라이언트와 서버는 TCP 연결을 통해 데이터를 전송할 수 있습니다. WebSocket 연결은 기본적으로 TCP 연결이므로 전송할 때마다 반복되는 헤더 데이터를 전달할 필요가 없으므로 폴링 및 Comet 기술에 비해 데이터 전송량이 훨씬 적습니다.

2. dwebsocket 설치

설치 방법:

1. pip를 통해

pip install  dwebsocket2

2. 로컬

압축 해제>하여 python setup.py install 실행

첨부 파일: 설치에 실패하고 ASCII 코드에 대한 메시지가 표시되면 readme에서 내용을 삭제하세요.

3 사용 방법

별도의 뷰에 대한 websocket 연결을 처리하려는 경우 표준 HTTP 요청을 뷰로 라우팅하는 accept_websocket 데코레이터를 사용할 수 있습니다. require_websocke 데코레이터 를 사용하면 WebSocket 연결만 허용되고 일반 HTTP 요청은 거부됩니다.

설정에서 MIDDLEWARE_CLASSES=dwebsocket.middleware.WebSocketMiddleware 설정을 추가하세요이렇게 하면 websocket에 대한 별도의 뷰 사용이 거부되며 로 장식되어야 합니다. accept_websocket 장치.

WEBSOCKET_ACCEPT_ALL=True로 설정하면 각 개별 보기에서 웹소켓

일부 메서드 및 속성

을 사용할 수 있습니다. 1.request.is_websocket()

웹소켓 요청인 경우 True를 반환하고, 일반 http 요청인 경우 False를 반환하는 방법을 사용하면 구별할 수 있습니다.

2.request.websocket

在一个websocket请求建立之后,这个请求将会有一个websocket属性,用来给客户端提供一个简单的api通讯,如果request.is_websocket()是False,这个属性将是None。

3.WebSocket.wait()

返回一个客户端发送的信息,在客户端关闭连接之前他不会返回任何值,这种情况下,方法将返回None

4.WebSocket.read()

 如果没有从客户端接收到新的消息,read方法会返回一个新的消息,如果没有,就不返回。这是一个替代wait的非阻塞方法

5.WebSocket.count_messages()

 返回消息队列数量

6.WebSocket.has_messages()

 如果有新消息返回True,否则返回False

7.WebSocket.send(message)

 向客户端发送消息

8.WebSocket.__iter__()

 websocket迭代器

四、干货

功能:让我们从客户端接收一条消息,将该消息发送回客户端并关闭连接。

1.新建一个django项目

Django에서 Websocket을 사용하는 방법에 대한 자세한 설명

2.新建index.html在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 () {
        $(&#39;#send_message&#39;).click(function () {
            var socket = new WebSocket("ws://" + window.location.host + "/echo_once");
            socket.onopen = function () {
                console.log(&#39;WebSocket open&#39;);//成功连接上Websocket
                socket.send($(&#39;#message&#39;).val());//发送数据到服务端
            };
            socket.onmessage = function (e) {
                console.log(&#39;message: &#39; + e.data);//打印服务端返回的数据
                $(&#39;#messagecontainer&#39;).prepend(&#39;<p>&#39; + e.data + &#39;</p>&#39;);
            };
        });
    });
    //]]></script>
</head>
<body>
<br>
<input type="text" id="message" value="Hello, World!"/>
<button type="button" id="send_message">发送 message</button>
<h1>Received Messages</h1>
<div id="messagecontainer">

</div>
</body>
</html>

3.app的views.py编写我们的服务端

from dwebsocket import require_websocket
@require_websocketdef echo_once(request):
    message = request.websocket.wait()
    request.websocket.send(message)

4.url路由设置

from demo import views as v
urlpatterns = [
    url(r'^index/', v.index),
    url(r'^echo_once', v.echo_once),
]

5.runserver运行,效果展示

Django에서 Websocket을 사용하는 방법에 대한 자세한 설명

可以看到,当我们点击按钮之后,服务端发送消息到客户端之后,就自动关闭了连接。

当然,我们也可以让服务端不自动关闭连接,接下来利用websocket和http Get写一个一样的功能的函数,

6.新建一个html,写一个新的客户端

<!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 () {
        $(&#39;#connect_websocket&#39;).click(function () {
            if (window.s) {
                window.s.close()
            }
            /*创建socket连接*/
            var socket = new WebSocket("ws://" + window.location.host + "/echo");
            socket.onopen = function () {
                console.log(&#39;WebSocket open&#39;);//成功连接上Websocket
            };
            socket.onmessage = function (e) {
                console.log(&#39;message: &#39; + e.data);//打印出服务端返回过来的数据
                $(&#39;#messagecontainer&#39;).prepend(&#39;<p>&#39; + e.data + &#39;</p>&#39;);
            };
            // Call onopen directly if socket is already open
            if (socket.readyState == WebSocket.OPEN) socket.onopen();
            window.s = socket;
        });
        $(&#39;#send_message&#39;).click(function () {
            //如果未连接到websocket
            if (!window.s) {
                alert("websocket未连接.");
            } else {
                window.s.send($(&#39;#message&#39;).val());//通过websocket发送数据
            }
        });
        $(&#39;#close_websocket&#39;).click(function () {
            if (window.s) {
                window.s.close();//关闭websocket
                console.log(&#39;websocket已关闭&#39;);
            }
        });

    });
    //]]></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>

7.在viws.py中加入新的方法

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


@accept_websocket
def echo(request):
    if not request.is_websocket():#判断是不是websocket连接
        try:#如果是普通的http方法
            message = request.GET[&#39;message&#39;]
            return HttpResponse(message)
        except:
            return render(request,&#39;index.html&#39;)
    else:
        for message in request.websocket:
            request.websocket.send(message)#发送消息到客户端

8.url.py

from demo import views as v
urlpatterns = [
    url(r&#39;^index2/&#39;, v.index2),
    url(r&#39;^echo$&#39;, v.echo),
]

9.runserver运行,看看效果

Django에서 Websocket을 사용하는 방법에 대한 자세한 설명

可以看到,只有当我们手动关闭连接时候,websocket才会关闭。

위 내용은 Django에서 Websocket을 사용하는 방법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.