参考: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断开,重新链接后,日志不被打印???