当前位置:   article > 正文

java-Websocket demo_java websocket demo

java websocket demo

1 概述
        WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工通信:允许服务器主动发送信息给客户端。 WebSocket协议跟http协议并没有太多的关系,不过使用了http的握手机制.

       http协议是应用很广的网络协议,它在通信前必须经过3次握手,它又分为短链接,长链接.短链接是每次请求都要三次握手才能发送自己的信息。即每一个request对应一个response。长链接是在一定的期限内保持链接。保持TCP连接不断开。客户端与服务器通信,必须要有客户端发起请求然后服务器返回结果。客户端是主动的,服务器是被动的。https是在http之上进行安全加密的协议,本质上还是http协议,通信方式还是一样.

       http协议在通信时,需要不停的进行连接,关闭,这是十分耗费资源的,而且效率低下.为了解决这个问题,WebSocket协议应运而生.它只需要进行一次握手就可以打开一条通信通道,并且不需要客户端发起查询请求,当有信息时,服务器会回调客户端.

2 demo
2.1 pom.xml
       如果不是使用Springboot进行开发的,需要引入javaee-api,@ServerEndpoint这个注解是Javaee标准里的注解,tomcat7以上已经对其进行了实现,如果是用传统方法使用tomcat发布项目,只要在pom文件中引入javaee标准即可使用.而Springboot使用内置的Tomcat,已经包含.
<!-- websocket,包括了配置WEB启动器 SpringMVC、Restful、jackson -->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

2.2 @ServerEndpoint
  首先要注入ServerEndpointExporter,这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint。不然会报无法连接.要注意,如果使用独立的servlet容器,而不是直接使用springboot的内置容器,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理。

  1. @Configuration
  2. public class WebSocketConfig {
  3. @Bean
  4. public ServerEndpointExporter serverEndpointExporter() {
  5. return new ServerEndpointExporter();
  6. }
  7. }

2.3 页面 

  1. <!DOCTYPE html>
  2. <html xmlns="http://www.w3.org/1999/html">
  3. <head>
  4. <meta charset="UTF-8">
  5. <script src="../js/jquery-3.1.1.min.js"></script>
  6. <title>Java后端WebSocket实现</title>
  7. </head>
  8. <body>
  9. 信息框:<input id="text" type="text"/>
  10. <button onclick="send()">发送</button>
  11. <hr/>
  12. <button onclick="closeWebSocket()">关闭WebSocket连接</button>
  13. <hr/>
  14. 收到的信息如下:</br>
  15. <div id="message">
  16. </div>
  17. </body>
  18. <script type="text/javascript">
  19. var webSocket = null;
  20. //判断当前浏览器是否支持WebSocket
  21. if ('WebSocket' in window) {
  22. //需要注意URL的格式,以ws:开头的
  23. webSocket = new WebSocket("ws://127.0.0.1:8888/webSocket");
  24. }
  25. else {
  26. alert('当前浏览器不支持WebSocket')
  27. }
  28. //连接发生错误的回调方法
  29. webSocket.onerror = function () {
  30. setMessageInnerHTML("WebSocket连接发生错误");
  31. };
  32. //连接成功建立的回调方法
  33. webSocket.onopen = function () {
  34. setMessageInnerHTML("WebSocket连接成功");
  35. }
  36. //接收到消息的回调方法
  37. webSocket.onmessage = function (event) {
  38. setMessageInnerHTML(event.data);
  39. }
  40. //连接关闭的回调方法
  41. webSocket.onclose = function () {
  42. setMessageInnerHTML("WebSocket连接关闭");
  43. }
  44. //监听窗口关闭事件,当窗口关闭时,主动去关闭webSocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
  45. window.onbeforeunload = function () {
  46. closeWebSocket();
  47. }
  48. //将消息显示在网页上
  49. var val = "";
  50. function setMessageInnerHTML(innerHTML) {
  51. var time = getCurTime();
  52. var temp = time+ '<br/>' + innerHTML + '<br/>';
  53. val = val + temp;
  54. $("#message").html(val);
  55. }
  56. //关闭WebSocket连接
  57. function closeWebSocket() {
  58. webSocket.close();
  59. }
  60. //发送消息
  61. function send() {
  62. var message = $('#text').val();
  63. webSocket.send(message);
  64. $("#text").val("");
  65. }
  66. function pad2(n) { return n < 10 ? '0' + n : n }
  67. function getCurTime() {
  68. var date = new Date();
  69. return date.getFullYear().toString() +"-"+ pad2(date.getMonth() + 1) +"-"+ pad2(date.getDate()) +" "+ pad2(date.getHours()) +":"+ pad2(date.getMinutes()) +":"+ pad2(date.getSeconds());
  70. }
  71. </script>
  72. </html>

 2.4 java-websocket代码

  1. package com.baibeiyun.environ;
  2. import java.io.IOException;
  3. import java.util.concurrent.CopyOnWriteArraySet;
  4. import javax.websocket.OnClose;
  5. import javax.websocket.OnError;
  6. import javax.websocket.OnMessage;
  7. import javax.websocket.OnOpen;
  8. import javax.websocket.Session;
  9. import javax.websocket.server.ServerEndpoint;
  10. import org.springframework.stereotype.Component;
  11. /**
  12. * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
  13. * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
  14. */
  15. @ServerEndpoint("/webSocket")
  16. @Component
  17. public class WebSocket {
  18. //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
  19. private static int onlineCount = 0;
  20. /**
  21. * concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
  22. * 若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
  23. */
  24. private static CopyOnWriteArraySet<WebSocket> webSocketSet = new CopyOnWriteArraySet<>();
  25. //与某个客户端的连接会话,需要通过它来给客户端发送数据
  26. private Session session;
  27. /**
  28. * 连接建立成功调用的方法
  29. * @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
  30. */
  31. @OnOpen
  32. public void onOpen(Session session) {
  33. this.session = session;
  34. webSocketSet.add(this); //加入set中
  35. addOnlineCount(); //在线数加1
  36. System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
  37. }
  38. /**
  39. * 连接关闭调用的方法
  40. */
  41. @OnClose
  42. public void onClose() {
  43. webSocketSet.remove(this); //从set中删除
  44. subOnlineCount(); //在线数减1
  45. System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
  46. }
  47. /**
  48. * 收到客户端消息后调用的方法
  49. * @param message 客户端发送过来的消息
  50. * @param session 可选的参数
  51. */
  52. @OnMessage
  53. public void onMessage(String message, Session session) {
  54. System.out.println("来自客户端的消息:" + message);
  55. //群发消息
  56. for (WebSocket item : webSocketSet) {
  57. try {
  58. item.sendMessage(message);
  59. } catch (IOException e) {
  60. e.printStackTrace();
  61. continue;
  62. }
  63. }
  64. }
  65. /**
  66. * 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
  67. * @param message
  68. * @throws IOException
  69. */
  70. public void sendMessage(String message) throws IOException {
  71. String respMsg = null;
  72. if ("1".equals(message)){
  73. respMsg = "Java";
  74. }else if ("2".equals(message)){
  75. respMsg = "python";
  76. }else if ("3".equals(message)){
  77. respMsg = "groovy";
  78. }else{
  79. respMsg = "欢迎访问!请根据如下规则获取您想要的内容:1:java 2:python 3:groovy";
  80. }
  81. this.session.getBasicRemote().sendText(respMsg);
  82. //this.session.getAsyncRemote().sendText(message);
  83. }
  84. /**
  85. * 发生错误时调用
  86. * @param session
  87. * @param error
  88. */
  89. @OnError
  90. public void onError(Session session, Throwable error) {
  91. System.out.println("发生错误");
  92. error.printStackTrace();
  93. }
  94. public static synchronized int getOnlineCount() {
  95. return onlineCount;
  96. }
  97. public static synchronized void addOnlineCount() {
  98. onlineCount++;
  99. }
  100. public static synchronized void subOnlineCount() {
  101. onlineCount--;
  102. }
  103. }

 


------------------

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/44336
推荐阅读
相关标签
  

闽ICP备14008679号