websocket 聊天室 demo ( tornado + nginx + wss + 在线demo)
生活随笔
收集整理的這篇文章主要介紹了
websocket 聊天室 demo ( tornado + nginx + wss + 在线demo)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在線demo(已停止服務)
?
前端代碼(來源網友,自己稍作修改):?
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title> WebSocket ChatRoom </title><style>*{margin: 0;padding: 0;}.box{width: 800px;margin-left: auto;margin-right: auto;margin-top: 25px;}#text{width: 685px;height: 130px;border: 1px solid skyblue;border-radius: 10px;font-size: 20px;text-indent: 1em;resize:none;outline: none;}#text::placeholder{color: skyblue;}.btn{width: 100px;margin: -27px 0 0px 8px;}#messages{padding-left: 10px;font-size: 25px;}#messages li{list-style: none;color: #000;line-height: 30px;font-size: 18px;}</style> </head> <body><div class="box"><div><textarea id="text" placeholder="請輸入您的內容"></textarea><a href="javascript:WebSocketSend();" class="btn btn-primary">發送</a></div><ul id="messages"></ul></div><script type="text/javascript">var mes = document.getElementById('messages');if('WebSocket' in window){ /*判斷瀏覽器是否支持WebSocket接口*//*創建創建 WebSocket 對象,協議本身使用新的ws://URL格式*/var Socket = new WebSocket("wss://10.0.0.189/wss/chat")/*連接建立時觸發*/Socket.onopen = function () {mes.innerHTML += "<br>連接已建立!╰( ̄▽ ̄)╮";//alert("連接已建立,可以進行通信")};/*客戶端接收服務端數據時觸發*/Socket.onmessage = function (ev) {var received_msg = ev.data; /*接受消息*/var aLi = "<li>" + received_msg + "</li>";mes.innerHTML += aLi;/*jq方式*/// $(mes).append($(aLi));};/*連接關閉時觸發*/Socket.onclose = function () {mes.innerHTML += "<br>連接已經關閉...(┬_┬)";};}else{/*瀏覽器不支持 WebSocket*/alert("您的瀏覽器不支持 WebSocket!");}function WebSocketSend() {/*form 里的Dom元素(input select checkbox textarea radio)都是value*/var send_msg = document.getElementById('text').value;//或者JQ中獲取// var send_msg = $("#text").val();/*使用連接發送消息*/Socket.send(send_msg);}</script> </body> </html>后端代碼(來源網友,自己稍作修改):
# coding:utf-8import tornado.web import tornado.ioloop import tornado.httpserver import tornado.options import os import datetimefrom tornado.web import RequestHandler from tornado.options import define, options from tornado.websocket import WebSocketHandlerdefine("port", default=8000, type=int)class IndexHandler(RequestHandler):def get(self):self.render("index.html")class ChatHandler(WebSocketHandler):users = set() # 用來存放在線用戶的容器def open(self):self.users.add(self) # 建立連接后添加用戶到容器中for u in self.users: # 向已在線用戶發送消息print("user count {}".format(len(self.users)))u.write_message(u"[%s]-[%s]-進入聊天室" % (self.request.remote_ip, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))print("{} enter room".format(self.request.remote_ip))def on_message(self, message):for u in self.users: # 向在線用戶廣播消息u.write_message(u"[%s]-[%s]-說:%s" % (self.request.remote_ip, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), message))print("{} says {}".format(self.request.remote_ip, message))def on_close(self):self.users.remove(self) # 用戶關閉連接后從容器中移除用戶for u in self.users:u.write_message(u"[%s]-[%s]-離開聊天室" % (self.request.remote_ip, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))print("{} leave room".format(self.request.remote_ip))def check_origin(self, origin):# 接受所有跨源流量return True# 若要允許來自站點任何子域的連接,您可以執行如下操作:# parsed_origin = urllib.parse.urlparse(origin)# return parsed_origin.netloc.endswith(".mydomain.com")if __name__ == '__main__':tornado.options.parse_command_line()app = tornado.web.Application([(r"/", IndexHandler),(r"/wss/chat", ChatHandler),],static_path = os.path.join(os.path.dirname(__file__), "static"),template_path = os.path.join(os.path.dirname(__file__), "template"),debug = True)http_server = tornado.httpserver.HTTPServer(app, xheaders=True)http_server.listen(options.port)tornado.ioloop.IOLoop.current().start()配置NGINX,運行代碼:
1. 準備工作: 找一臺虛擬機或服務器, 安裝nginx, python3.6, tornado,把后端代碼拷貝上去。
2. nginx配置:
/etc/nginx/conf.d 下新增個文件 wss.conf
server_tokens off;upstream wss_svr {server 127.0.0.1:8000; }server{listen 80;server_name 10.0.0.189;add_header Strict-Transport-Security max-age=15768000;return 301 https://$server_name$request_uri; }server {listen 443;server_name 10.0.0.189;ssl on;index index.html index.htm;ssl_certificate cert/10.0.0.189.crt;ssl_certificate_key cert/10.0.0.189.key;ssl_session_timeout 5m;ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;ssl_protocols TLSv1 TLSv1.1 TLSv1.2;ssl_prefer_server_ciphers on;location /ws {alias /var/www/web_chat/;index index.html;}location /wss {proxy_redirect off;proxy_pass http://wss_svr;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $remote_addr:$remote_port;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection upgrade;proxy_read_timeout 180s;} }3. 本地生成證書,放在?/etc/nginx/cert 目錄下,?證書腳本如下,生成時輸入服務器ip地址
read -p "Enter your domain [www.example.com]: " DOMAINecho "Create server key..." openssl genrsa -des3 -out $DOMAIN.key 1024echo "Create server certificate signing request..." SUBJECT="/C=US/ST=Mars/L=iTranswarp/O=iTranswarp/OU=iTranswarp/CN=$DOMAIN" openssl req -new -subj $SUBJECT -key $DOMAIN.key -out $DOMAIN.csrecho "Remove password..." mv $DOMAIN.key $DOMAIN.origin.key openssl rsa -in $DOMAIN.origin.key -out $DOMAIN.keyecho "Sign SSL certificate..." openssl x509 -req -days 3650 -in $DOMAIN.csr -signkey $DOMAIN.key -out $DOMAIN.crtecho "TODO:" echo "Copy $DOMAIN.crt to /etc/nginx/ssl/$DOMAIN.crt" echo "Copy $DOMAIN.key to /etc/nginx/ssl/$DOMAIN.key"echo "Add configuration in nginx:" echo "server {" echo " ..." echo " listen 443 ssl;" echo " ssl_certificate /etc/nginx/ssl/$DOMAIN.crt;" echo " ssl_certificate_key /etc/nginx/ssl/$DOMAIN.key;" echo "}"4. 啟動nginx
service nginx start
5. 運行代碼
python wss.py
6. 打開前端代碼寫的html,即可看到界面
效果
?打開時頁面:
輸入文字時:
服務器打印:
?問題:
服務器打印的遠端IP成了127.0.0.1,不是真實的IP地址。
這個問題涉及2個地方,一個是nginx配置,一個是tornado代碼
nginx配置是沒得問題的:
那就是tornado了,因為沒加??xheaders=True
http_server = tornado.httpserver.HTTPServer(app, xheaders=True)OK,完美解決
?
總結
以上是生活随笔為你收集整理的websocket 聊天室 demo ( tornado + nginx + wss + 在线demo)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PHP实现中文字符串截取无乱码
- 下一篇: python 入门学习