参考:https://www.cnblogs.com/baijinshuo/p/10550484.html

1、创建app 

      python manager.py startapp websocketapp

2、为app添加路由

    path('websocketapp/', include('websocketapp.urls')),

3、配置app

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'websocketapp',
]

4、templates 配置

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(BASE_DIR, 'websocketapp/templates'),
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

5、websocketapp 中添加模板templates/html

6、websocketapp 中新建路由 urls.py

from django.contrib import admin
from django.urls import path, include

from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from websocketapp import views as v

urlpatterns = [
    path('autolog', v.autolog, name="autolog"),
    path('autolog_echo', v.autolog_echo),
]

urlpatterns += staticfiles_urlpatterns()

7、websocketapp 中添加视图方法autolog, autolog_echo

from django.shortcuts import render

# Create your views here.
from django.shortcuts import render
from dwebsocket.decorators import accept_websocket, require_websocket
from django.http import HttpResponse

import threading
import time
import subprocess, sys
import os, json

from .server import runserver # 引入多线程服务器

def autolog(request):
    return render(request, 'html/autolog.html')


@accept_websocket
def autolog_echo(request):
    if not request.is_websocket():  # 判断是不是websocket连接
        try:  # 如果是普通的http方法
            message = request.GET['message']
            return HttpResponse(message)
        except:
            return render(request, 'html/autolog.html')
    else:
        for message in request.websocket:
            if b'runserver' == message:
                IS_WIN32 = 'win32' in str(sys.platform).lower()
                if IS_WIN32:
                    runserver("127.0.0.1", 50007, request)
            elif b'closedserver' == message:
                request.websocket.send('closedserver')

8、创建多线程服务器server.py

# Create your views here.
import socket
import threading
import os, json
from .log import Logger

log = Logger('all.log', level='debug')


# 多线程服务器
def handle_conn(log, sock, address, request1):
    t = threading.Thread(target=process_conn, args=(sock, address, request1))
    t.start()


def process_conn(sock, address, request1):
    print(threading.current_thread())
    data = "hello " + str(address)
    sock.send(data.encode("utf-8"))
    request1.websocket.send(json.dumps(data))

    while True:  # 多次为一个客户端服务
        try:
            recv_data = sock.recv(1024).decode("gbk", 'ignore')
            # 如果 recv 解堵塞,客户端有两种方式 1. 发送了数据 2. 关闭了连接
            if recv_data:
                try:
                    request1.websocket.send(json.dumps(recv_data.strip()))
                except Exception as e:
                    log.logger.log(e)
                log.logger.info(recv_data)
        except Exception as e:
            request1.websocket.send(json.dumps(("close socket.. %s ") % (e)))
            sock.close()
            break


def runserver(ip, port, request1):
    # 1. create socket
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 2. bind local information
    tcp_server_socket.bind((ip, port))
    # 3.
    tcp_server_socket.listen()
    # 4. accept connection from client
    # 类似你在等待别人的电话到来
    # 元组解包
    while True:
        request1.websocket.send("waitting for client ........")
        new_client_socket, client_addr = tcp_server_socket.accept()
        handle_conn(log, new_client_socket, client_addr, request1)

9、websocketapp 的模板templates添加autolog.html

{% extends 'html/index.html' %}
{% block JSLink %}
    <script type="text/javascript">
        function reconvert(str) {
            str = str.replace(/(\\u)(\w{1,4})/gi, function ($0) {
                return (String.fromCharCode(parseInt((escape($0).replace(/(%5Cu)(\w{1,4})/g, "$2")), 16)));
            });
            str = str.replace(/(&#x)(\w{1,4});/gi, function ($0) {
                return String.fromCharCode(parseInt(escape($0).replace(/(%26%23x)(\w{1,4})(%3B)/g, "$2"), 16));
            });
            str = str.replace(/(&#)(\d{1,6});/gi, function ($0) {
                return String.fromCharCode(parseInt(escape($0).replace(/(%26%23)(\d{1,6})(%3B)/g, "$2")));
            });
            return str;
        }

        //<![CDATA[
        $(function () {
            var socket = new WebSocket("ws://" + window.location.host + "/websocketapp/autolog_echo");  // websocket接口
            if (window.s) {
                window.s.close()
            }
            /*创建socket连接*/
            socket.onopen = function () {
                console.log('WebSocket open');//成功连接上Websocket
                {#    发送执行脚本 #}

            };
            // Call onopen directly if socket is already open
            if (socket.readyState == WebSocket.OPEN) socket.onopen();

            window.s = socket;

            socket.onmessage = function (e) {
                $('#messagecontainer').prepend('<p>' + reconvert(e.data) + '</p>');  //日志显示
            };

            $('#connect_websocket').click(function () {
                window.s.send("runserver");
            });

            $('#close_websocket').click(function () {
                if (window.s) {
                    window.s.send("closedserver");
                    window.s.close();//关闭websocket
                    console.log('websocket已关闭');
                }
            });
        });
        //]]></script>
{% endblock %}

{% block ContainsPageContentr %}
    {% load static %}
    <!-- Content Wrapper. Contains page content -->
    <div class="content-wrapper">
        <!-- Content Header (Page header) -->
        <div class="content-header">
            <div class="container-fluid">
                <div class="row mb-2">
                    <div class="col-sm-6">
                        <h1 class="m-0">实时日志</h1>
                    </div><!-- /.col -->
                    <div class="col-sm-6">
                        <ol class="breadcrumb float-sm-right">
                            <li class="breadcrumb-item"><a href="{% url 'index' %}">Home</a></li>
                            <li class="breadcrumb-item active">实时日志</li>
                        </ol>
                    </div><!-- /.col -->
                </div><!-- /.row -->
            </div><!-- /.container-fluid -->
        </div>
        <!-- /.content-header -->

        <!-- Main content -->
        <div class="content">
            <div class="container-fluid">
                <div class="row">
                    <div class="col-lg-12" id="autolog">
                        <button type="button" id="connect_websocket">开启服务</button>
                        <button type="button" id="close_websocket">结束服务</button>
                        <div id="messagecontainer" style="overflow: hidden;font-size:12px">
                        </div>
                    </div>
                </div>
                <!-- /.row -->
            </div><!-- /.container-fluid -->
        </div>
        <!-- /.content -->
    </div>
    <!-- /.content-wrapper -->
{% endblock %}

 

 

 

 

问题:

    页面被刷新后,websocket断开,重新链接后,日志不被打印???

 

posted on 2021-12-23 10:44  Old-Kang  阅读(624)  评论(1编辑  收藏  举报