Springboot配置websocket,https使用 WebSocket 连接 | 字数总计: 1.5k | 阅读时长: 5分钟 | 阅读量: |
提示:本文简单介绍websocket与http的区别及如何在项目中使用websocket,以springboot项目为例
一、http协议与websocket协议区别
WebSocket
一种在单个连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
用于Web应用中需要实现动态刷新的场景,大量数据定时刷新,数据轮询等操作场景,例如在线聊天、网页游戏、实时数据分析等。支持双向通信,实时性更强,更好的二进制支持,更小的控制开销:协议包头较小。同时支持扩展。
HTTP
HTTP一种单向的请求-响应协议,即客户端向服务器发送请求,服务器响应后连接关闭。这种模式限制了服务器主动向客户端推送信息的能力。用户想刷新一次数据就需要请求一次后台。
HTTP更适合于传输静态内容或简单的请求-响应场景,如网页浏览。
二、使用步骤
1.引入库
1 2 3 4 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-websocket</artifactId > </dependency >
2.配置websocket
代码如下(示例):创建WebSocketConfig
1 2 3 4 5 6 7 8 @Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter () { return new ServerEndpointExporter(); } }
代码如下(示例):创建websocket
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 @Component @ServerEndpoint("/websocket") public class WebSocket { private final static Logger log = LoggerFactory.getLogger(WebSocket.class); private Session session; @OnOpen public void onOpen (Session session) { this .session = session; webSocketSet.add(this ); log.info("【websocket消息】有新的连接, 总数:{}" , webSocketSet.size()); } @OnClose public void onClose () { webSocketSet.remove(this ); log.info("【websocket消息】连接断开, 总数:{}" , webSocketSet.size()); } @OnMessage public void onMessage (String message) { log.info("【websocket消息】收到客户端发来的消息:{}" , message); } public static void sendMessage (String message) { for (WebSocket webSocket : webSocketSet) { log.info("【websocket消息】广播消息, message={}" , message); try { webSocket.session.getBasicRemote().sendText(message); } catch (Exception e) { e.printStackTrace(); } } } }
3.消息互发 例如:在前端有一个员工表查询页面,要求实现员工表新增数据时,自动刷新员工list页面。
3.1 后台通知
1 2 3 4 5 6 7 8 9 10 public Map<String, Object> addStaff (Staff staff, Map<String, Object> resultMap) { boolean success = staffDao.addStaff(staff); if (success) { WebSocket.sendMessage("add staff data" ); resultMap.put("data" , 1 ); } else { resultMap.put("data" , 0 ); } return resultMap; }
3.2 前端接收消息并处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 <script type="text/javascript" > var websocket = null ; if ('WebSocket' in window ) { websocket = new WebSocket("ws://localhost:8082/websocket" ); } else { alert('Not support websocket' ) } websocket.onerror = function ( ) { console .log("发生错误" ) }; websocket.onopen = function (event ) { console .log("建立连接" ) } websocket.onmessage = function (event ) { console .log(event.data) window .location.href ="/staff/staffPage" ; } websocket.onclose = function ( ) { console .log("关闭连接" ) } window .onbeforeunload = function ( ) { alert("已关闭连接" ); websocket.close(); } function closeWebSocket ( ) { alert("已关闭连接" ); websocket.close(); } </script>
到这里基本上项目使用websocket动态刷新就完成了,但是这也是基于本地的项目。如果是部署到linux,使用ssl连接的情况下,这种配置又会失效,原因是在默认情况下,Websocket 的 ws 协议使用 80 端口,运行在TLS之上时,wss 协议默认使用 443 端口。其实说白了,wss 就是 ws 基于 SSL 的安全传输。
4.配置服务器https域名
nginx配置域名证书的过程不做介绍,可以参考前面的文章 Nginx配置多个ssl域名项目 按照上面的理论,是不是只要将路径的ws替换成wss,路径改为域名即可呢?
1 2 3 websocket = new WebSocket("ws://localhost:8082/websocket");//替换前 websocket = new WebSocket("wss://www.abc.com/websocket");//替换后
替换后发现报错了 This request has been blocked; this endpoint must be available over wss. wss协议实际是websocket+ssl,是在websocket协议上加入ssl层,类似https(http+ssl),这个时候就需要检查配置的域名证书是否有效,如果证书确认没问题,还需要配置nginx
解决办法 :nginx配置websocket,配置完成一定要重启nginx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 server{ listen 80; server_name www.abc.com; rewrite ^(.*) https://$server_name$1 permanent; //配置带不带www都可以访问通 } server { listen 443 ssl; server_name www.abc.com; ssl_certificate certificate_ssl/abc.com.pem; //自己存放证书的位置 ssl_certificate_key certificate_ssl/abc.com.key; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; client_max_body_size 50m; location / { root html; index index.html index.htm; proxy_set_header x-forwarded-for $remote_addr; proxy_pass http://127.0.0.1:8082/; # 以下为websocket配置关键步骤 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; } error_page 500 502 503 504 /upgrade.html; location = /upgrade.html { root html; } }
不出意外应该大功告成了,如果期间还有不同报错,根据报错内容解决相关问题。