在线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)相关推荐

  1. golang websocket 聊天室demo

    近期偶然的机会看到一些go的websocket技术方案,顺便写了个demo,玩了一下: 首先安装websocket包 go get code.google.com/p/go.net/websocket ...

  2. 微信团队分享:微信直播聊天室单房间1500万在线的消息架构演进之路

    本文由微信开发团队工程师" kellyliang"原创发表于"微信后台团队"公众号,收录时有修订和改动. 1.引言 随着直播和类直播场景在微信内的增长,这些业务 ...

  3. SpringBoot(WebSocket聊天室)

    WebSocket 事件 Websocket 使用 ws 或 wss 的统⼀资源标志符,类似于 HTTPS,其中 wss 表示在 TLS 之上的 Websocket. ws://example.com ...

  4. java控制层创建websocket_用Java构建一个简单的WebSocket聊天室

    前言 首先对于一个简单的聊天室,大家应该都有一定的概念了,这里我们省略用户模块的讲解,而是单纯的先说说聊天室的几个功能:自我对话.好友交流.群聊.离线消息等. 今天我们要做的demo就能帮我们做到这一 ...

  5. WebSocket聊天室

    WebSocket聊天室 HTML5 WebSocket实现了服务器与浏览器的双向通讯,双向通讯使服务器消息推送开发更加简单,最常见的就是即时通讯和对信息实时性要求比较高的应用.以前的服务器消息推送大 ...

  6. swoole+redis(websocket聊天室demo)

    websocket是不同于http的另外一种网络通信协议,能够进行双向通信,基于此,可开发出各种实时通信产品,我简单做了个聊天室demo,顺便分享一下. PHP的swoole扩展,正如作者所说,是PH ...

  7. django+vue3实现websocket聊天室(群聊)

    1.如何实现聊天功能 2.什么是websocket 2.1解释什么叫全双工,半双工,单工 3.websocker的概念 4.websocket的优点 5.django ,vue如何实现websocke ...

  8. 微信小程序websocket聊天室

    背景 最近做了一个微信小程序的即时通讯功能,之前我也做过node.js的websocket服务,不过是在web端应用的socket.io服务.小程序本身对http.websocket等连接均有诸多限制 ...

  9. 微信直播聊天室单房间1500万在线的消息架构演进之路

    1.引言 随着直播和类直播场景在微信内的增长,这些业务对临时消息(在线状态时的实时消息)通道的需求日益增长,直播聊天室组件应运而生.直播聊天室组件是一个基于房间的临时消息信道,主要提供消息收发.在线状 ...

  10. WebSocket聊天室业务场景分析

    1. 需求描述 假设需要建立一个Web聊天室,可以理解为QQ的Web版本.首先考虑最简单的需求,即实现用户A和用户B之间的聊天.而实现的技术采用WebSocket.业务场景如下图所示. 2. 场景分析 ...

最新文章

  1. ldconfig动态链接库管理以及修改ld.so.conf.d
  2. 从程序员到项目经理(20):让员工为目标而干活
  3. Tableau必知必会之如何快速制作 词云(文字云)
  4. 使用Nodejs实现的小说爬虫
  5. ISE中使用DDR3例程的生成步骤与仿真过程
  6. 结构体中的自然对界法则
  7. 机械优化设计进退法c语言程序,机械优化设计powell法程序
  8. k3刷机 重置_斐讯K3刷LEDE固件成功刷机教程
  9. java本学期期末学员,本学期期末学员共参加了3门课的考试,即Java,C,SQL,编写方法计算每位学员3门课的平均分,...
  10. Operator基础:1: Operator Framework简介
  11. 使用meshBaker合并多个mesh进行优化
  12. Bazinga(HDU5510+KMP)
  13. HtmlHelp调用chm帮助文档使用
  14. MongoDB 索引(一)
  15. poj 1125 Stockbroker(多源最短路径)
  16. 今天15:00| ICML专场四,7位PhD来袭!
  17. Ubuntu上使用微信
  18. PGSQL插入或者更新的语法
  19. 润乾报表中API动态合并格,连续显示行号
  20. frp-免费内网穿透

热门文章

  1. 地图采集商家,附近商家,最新企业信息采集软件的使用教程
  2. html+css入门(参考b站黑马
  3. 3.1词典搜索的数据结构与通配符查询
  4. 【libjpeg-turbo】安装指南[mac版]
  5. hbuild html5打包apk,使用HBuilder打包5+App
  6. python爬取淘宝评论_抓取淘宝某产品评论(附视频教程)
  7. KubeSphere 3.3.0 离线安装教程
  8. Kotlin 一种以服务为基础的APP架构及源码示例
  9. oracle 数据库er生成,oracle数据库生成er图
  10. android 自定义唤醒词,星星1号语音升级 中兴语音助手实现可自定义唤醒词