分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 前端开发

django + nginx + uwsgi + websocket

发布时间:2023-09-06 01:47责任编辑:沈小雨关键词:nginxdjangowebsocket

  最近使用django框架做了一个简单的聊天机器人demo, 开发的过程中使用了django自带的websocket模块,当使用django框架自带的wsgi服务去启动的话,没有什么问题。如果要使用uwsgi启动的话,会报错:handshake的返回400,也就是客户端不合法。针对这边些问题,我去查询了官方文档,发现了我问题:

  1. django-websocket 是旧版本的,现在已经没有人维护了。dwebsocket是新版的,推荐使用dwebsocket;

  2.使用uwsgi启动的话,需要原有uwsgi.ini 配置信息下添加两行配置信息 

    2.1 websocket要使用uwsgi自带的websocket模块  

    2.2 # 加载项目配置
      DJANGO_SETTINGS_MODULE=py_webserver.settings
      WEBSOCKET_FACTORY_CLASS="dwebsocket.backends.uwsgi.factory.uWsgiWebSocketFactory"

    2.3  启动脚本如下:uwsgi --ini ./conf/uwsgi.ini --http-websockets

  3.在nginx.conf配置文件中添加几行配置文件即可解决问题

 整个demo以及配置信息如下:

 1.项目结构:

   

2.pywebserever项目代码:

 conf 模块下的代码:

  mysql.ini

[mysqlsettings]
dbname = webSocket_chatbot
host = 127.0.0.1
port = 3306
uname = root
passwd = mysql

  pyweb_log.ini

[logs]
mail_level = ERROR
tofile_level = DEBUG
loggers_level = INFO

  uwsgi.ini (uwsgi启动项目的时候需要的配置文件)

[uwsgi]
#使用nginx连接时使用
socket=127.0.0.1:8080

#直接做web服务器使用
#http=127.0.0.1:8080

# 启动主进程
master=True
pidfile=uwsgi.pid

processes=4
threads=2

#项目目录
chdir=/home/python/Desktop/test_code/py_webserver

#项目中wsgi.py文件的目录,相对于项目目录
wsgi-file=py_webserver/wsgi.py

# 设置日志目录
daemonize=logs/uwsgi.log

# 设置缓存
buffer-size=32768

# 当服务器退出的时候自动删除unix socket 文件和pid 文件
vacuum = true

# 加载项目配置(django + websocket时需要配置的信息)
DJANGO_SETTINGS_MODULE=py_webserver.settings
WEBSOCKET_FACTORY_CLASS="dwebsocket.backends.uwsgi.factory.uWsgiWebSocketFactory"

 pywebserver模块下的代码:

  urls.py: 

from django.urls import path, includefrom django.contrib import adminurlpatterns = [ ???path(‘admin/‘, admin.site.urls), ???path(‘‘, include(‘webwork.urls‘)),]

  settings.py:

import osimport configparser# Build paths inside the project like this: os.path.join(BASE_DIR, ...)BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))conf = configparser.ConfigParser()# Application definitionINSTALLED_APPS = [ ???‘django.contrib.admin‘, ???‘django.contrib.auth‘, ???‘django.contrib.contenttypes‘, ???‘django.contrib.sessions‘, ???‘django.contrib.messages‘, ???‘django.contrib.staticfiles‘, ???‘webwork‘, ???# 此处注册应用]# Database# https://docs.djangoproject.com/en/1.10/ref/settings/#databasesconf.read(BASE_DIR + "/conf/mysql.ini")DATABASES = { ???‘default‘: { ???????‘ENGINE‘: ‘django.db.backends.mysql‘, ???????‘NAME‘: conf.get("mysqlsettings", "dbname"), ???????"Host":conf.get("mysqlsettings", "host"), ???????"PORT":conf.get("mysqlsettings", "port"), ???????"USER":conf.get("mysqlsettings", "uname"), ???????"PASSWORD":conf.get("mysqlsettings", "passwd"), ???????"CONN_MAX_AGE":600 ?????# 增加连接池,保持数据 长连接600秒 ???}}# Logs配置conf.read(BASE_DIR + "/conf/pyweb_log.ini")LOGGING = { ???‘version‘: 1, ???‘disable_existing_loggers‘: False, ???‘formatters‘: { ???????‘standard‘: { ???????????‘format‘: ‘[%(asctime)s] %(levelname)s [%(name)s.%(funcName)s:%(lineno)d] %(message)s‘, ???????????‘datefmt‘: ‘%Y-%m-%d %H:%M:%S‘ ???????}, ???}, ???‘filters‘: { ???}, ???‘handlers‘: { ???????‘mail_admins‘: { ???????????‘level‘: conf.get("logs", "mail_level"), ???????????‘class‘: ‘django.utils.log.AdminEmailHandler‘, ???????????‘formatter‘: ‘standard‘, ???????}, ???????‘tofile‘: { ???????????‘level‘: conf.get("logs", "tofile_level"), ???????????‘class‘: ‘logging.FileHandler‘, ???????????‘formatter‘: ‘standard‘, ???????????‘filename‘: os.path.join(BASE_DIR, ‘logs/py_web.log‘), ???????}, ???}, ???‘loggers‘: { ???????‘django‘: { ???????????‘handlers‘: [‘tofile‘], ???????????‘level‘: conf.get("logs", "loggers_level"), ???????????‘propagate‘: True, ???????}, ???}}

   __inint__.py

import pymysqlpymysql.install_as_MySQLdb()

 template模块下的代码:

  chat.html  

<!DOCTYPE html><html lang="en"><head> ???<meta charset="UTF-8"> ???<title>Test Django Channels</title></head><body><div style="text-align: center;margin-top: 50px"> ???<input id="message" type="text" style="width: 300px" placeholder="输入消息"> ???<button id="send-message" style="width:80px;margin-left:20px;">发送</button> ???<button id="close-message" style="width:80px;margin-left:20px;">关闭</button> ???<button id="connect-message" style="...">登录连接</button> ???<button id="test" style="...">测试长连接</button></div><table id="show-message" style="width: 410px;margin: 0 auto;margin-top: 10px"> ???<tr> ???????<td style="text-align: center; border-bottom:1px dashed #000;"><strong>聊天记录</strong></td> ???</tr></table></body><script src="/static/js/jquery-3.2.1.min.js"></script><script> ???var socket = new WebSocket(‘ws://‘ + window.location.host + ‘/users/‘); ???socket.onmessage = function (message) { ???????updateLog("机器人", message.data); ???????$("#message").val(""); ???????$("#message").focus(); ???}; ???socket.onopen = function () { ???}; ???$("#connect-message").click(function () { ???????socket = new WebSocket(‘ws://‘ + window.location.host + ‘/users/‘); ???????socket.onmessage = function (message) { ???????????updateLog("机器人", message); ???????????$("#message").val(""); ???????????$("#message").focus(); ???????}; ???????socket.onopen = function () { ???????}; ???}); ???$("#close-message").click(function () { ???????updateLog("机器人", "你好,此次服务结束"); ???????socket.close() ???}); ???$("#send-message").click(function () { ???????var inputText = $("#message").val(); ???????if (typeof(inputText) == "undefined" || inputText.length < 1) { ???????????alert("没有输入信息"); ???????} ???????else { ???????????var msg = {"text": inputText}; ???????????socket.send(JSON.stringify(msg)); ???????????updateLog("你", inputText); ???????} ???}); ???function updateLog(name, message) { ???????var chat = $("#show-message"); ???????var ele = "<tr><td>" + name + ": " + message + "</td></tr>"; ???????chat.append(ele); ???} ???$("#test").click(function () { ???????alert(socket.readyState); ???})</script></html>

  webwork模块下的代码:

  models.py

 1 from django.db import models 2 ?3 # Create your models here. 4 ?5 class MysqlModel(models.Model): 6 ????info = models.CharField(max_length=100) 7 ????save_time = models.DateTimeField() 8 ?9 ????class Meta:10 ????????db_table = "t_chatbot_test"

  urls.py

1 from django.urls import include, path2 from webwork.views import ChatView, user3 4 urlpatterns = [5 ????path(‘‘, ChatView.as_view(), name=‘chat‘),6 ????path("users/", user, name="users")7 8 ]

  view.py

 1 from django.shortcuts import render 2 from django.views.generic.base import View 3 from .models import MysqlModel 4 import time 5 import uwsgi 6 import json 7 import logging 8 ?9 10 logger = logging.getLogger("django")11 # Create your views here.12 13 class ChatView(View):14 ????"""加载前端页面"""15 ????@staticmethod16 ????def get(request):17 ????????return render(request, "webwork/chat.html")18 19 20 def user(request):21 ????"""接受websocket传递过来的信息"""22 ????uwsgi.websocket_handshake()23 ????uwsgi.websocket_send("你还,很高心为你服务")24 ????while True:25 ????????msg = uwsgi.websocket_recv()26 ????????msg = msg.decode()27 ????????data = json.loads(msg)28 ????????data_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))29 ????????talk_words = MysqlModel()30 ????????talk_words.info = data["text"]31 ????????talk_words.save_time = data_time32 ????????try:33 ????????????talk_words.save()34 ????????????talks = MysqlModel.objects.all()35 ????????except Exception as ret:36 ????????????logger.info("save_data:" + str(ret))37 ????????else:38 ????????????for talk in talks:39 ????????????????logger.info("talk_info:" + talk.info)40 ????????uwsgi.websocket_send(data["text"])

requirements.txt 中的依赖包

gi-redis==1.0.0asgiref==1.0.0attrs==16.3.0autobahn==0.17.1Automat==0.5.0channels==1.0.3constantly==15.1.0daphne==1.0.3Django==2.0.3incremental==16.10.1msgpack-python==0.4.8PyMySQL==0.8.0pytz==2018.3redis==2.10.5six==1.10.0Twisted==17.1.0txaio==2.6.1txredisapi==1.4.4uWSGI==2.0.17zope.interface==4.3.3

3.uwsgi的配置:

3.1 安装uwsgi ???pip install uwsgi3.2 在项目下的conf文件下创建uwsgi.ini文件,具体配置信息如上边的uwsgi.ini文件所示3.3 启动uwsgi:uwsgi --ini ./conf/uwsgi.ini --http-websockets3.4 ?查看uwsgi启动状态:ps -ef|grep uwsgi3.5 启动之后在浏览器输入:127.0.0.1;8080 查看uwsgi服务器的状态3.6 ?停止启动状态 ???uwsgi -- stop uwsgi.pid
4.nginx的配置:
# 安装nginx并验证是否安装正确
4.1 下载nginx后放到桌面上,解压缩 ?tar zxvf nginx-1.6.3.tar.gz4.2 进入nginx-1.6.3目录,依次执行以下命令进行安装 ?????./configure (--prefix=<path>,nginx 指定安装根目录) ???make ???sudo make install4.3 默认安装到/usr/local/nginx/目录,进入此目录4.4 启动: sudo sbin/nginx

4.5.查看进程 ??ps -ef|grep nginx

4.6 浏览器检测ngnix是否启动:http://127.0.0.1/4.7 关闭ngnix服务器:sudo sbin/nginx -s stop

# nginx指向uwsgi
 4.8.主要配置节点:对于处理http协议的请求,主要配置三个节点
  • http:表示所有的http请求的处理
  • server:监听端口,绑定服务器
  • location:匹配请求路径,转到相应的处理
  server {
     listen ?80;
     server_name localhost;

  ???????location / { ???????????#将所有的参数转到uwsgi下 ???????????include uwsgi_params;; ???????????#uwsgi的ip与端口 ???????????uwsgi_pass 127.0.0.1:8080; ????????????????????? # websocket的匹配 ????????????proxy_redirect off; ???????????proxy_http_version 1.1; ???????????proxy_set_header Upgrade $http_upgrade; ???????????proxy_set_header Connection "upgrade"; ???????????}

    # 注释掉nginx server下的这几行配置

      #location / {
???????        # ?root ??html;
???????        # ???index ?index.html index.htm;
???????        # }

 
  
 4.9.所有的静态文件都会由nginx处理,不会将请求转到uwsgi
    4.9.1.先生成静态文件目录   此项目我创建静态文件路径:/home/python/Desktop/test_code/django_static/websocket_static
    4.9.2.django的settings增加静态文件配置   

    STATIC_ROOT="/home/python/Desktop/test_code/django_static/websocket_static"
     STATIC_URL = ‘/static/‘

     # 将STATICFILES_DIRS的参数注释掉

   4.9.3 收集静态文件到 STATIC_ROOT 中

 4.10 在nginx.conf 的server下增加静态文件配置  

    location /static {
???????????    alias /home/python/Desktop/test_code/django_static/websocket_static;
???????}

 
  

   

    

django + nginx + uwsgi + websocket

原文地址:https://www.cnblogs.com/lph-shares/p/8708786.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved