Java Websocket实例【服务端与客户端实现全双工通讯】

2024-09-09 05:08

本文主要是介绍Java Websocket实例【服务端与客户端实现全双工通讯】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Java Websocket实例【服务端与客户端实现全双工通讯】


现很多网站为了实现即时通讯,所用的技术都是轮询(polling)。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发

HTTP request,然后由服务器返回最新的数据给客服端的浏览器。这种传统的HTTP request 的模式带来很明显的缺点 – 浏

览器需要不断的向服务器发出请求,然而HTTP request header是非常长的,里面包含的数据可能只是一个很小的值,这样会占

用很多的带宽。WebSocket提供了一个受欢迎的技术,以替代我们过去几年一直在用的Ajax技术。

一、什么是WebSocket API?

WebSocket API是下一代客户端-服务器的异步通信方法。该通信取代了单个的TCP套接字,使用wswss协议,可用于任意的

客户端和服务器程序。WebSocket目前由W3C进行标准化。WebSocket已经受到Firefox 4Chrome 4Opera 10.70以及Safari 5

浏览器的支持。

WebSocket API最伟大之处在于服务器和客户端可以在给定的时间范围内的任意时刻,相互推送信息。WebSocket并不限于以

Ajax(XHR)方式通信,因为Ajax技术需要客户端发起请求,而WebSocket服务器和客户端可以彼此相互推送信息;XHR受到域

的限制,而WebSocket允许跨域通信。

Ajax技术很聪明的一点是没有设计要使用的方式。WebSocket为指定目标创建,用于双向推送消息。

那么我就开始我在项目中对websocket的使用,首先使用的是J2EE7的架包。

 

架包加完之后,只需要再添加2个类就可以实现使用的功能了。

首先添加一个Java类,WebsocketController.java

[java]  view plain copy
  1. package com.lwl.activemq.controller.websocket;  
  2.   
  3. import java.util.Map;  
  4. import java.util.concurrent.ConcurrentHashMap;  
  5.   
  6. import javax.websocket.*;  
  7. import javax.websocket.server.PathParam;  
  8. import javax.websocket.server.ServerEndpoint;  
  9.   
  10.   
  11. import org.slf4j.Logger;  
  12. import org.slf4j.LoggerFactory;  
  13. /** 
  14.  * 功能说明:websocket处理类, 使用J2EE7的标准 
  15.  * @author Administrator 
  16.  * @create 2016-8-11 下午4:08:35 
  17.  * @version 1.0 
  18.  */  
  19. @ServerEndpoint("/websocket/{myWebsocket}")  
  20. public class WebsocketController {  
  21.     private static final Logger logger = LoggerFactory.getLogger(WebsocketController.class);  
  22.   
  23.     public static Map<String, Session> clients = new ConcurrentHashMap<String, Session>();  
  24.   
  25.     /** 
  26.      * 打开连接时触发 
  27.      * @param myWebsocket 
  28.      * @param session 
  29.      */  
  30.     @OnOpen  
  31.     public void onOpen(@PathParam("myWebsocket") String myWebsocket, Session session){  
  32.         logger.info("Websocket Start Connecting:" + myWebsocket);  
  33.         System.out.println("进入:"+myWebsocket);  
  34.         clients.put(myWebsocket, session);  
  35.     }  
  36.   
  37.     /** 
  38.      * 收到客户端消息时触发 
  39.      * @param myWebsocket 
  40.      * @param message 
  41.      * @return 
  42.      */  
  43.     @OnMessage  
  44.     public String onMessage(@PathParam("myWebsocket") String myWebsocket, String message) {  
  45.         return "Got your message ("+ message +").Thanks !";  
  46.     }  
  47.   
  48.     /** 
  49.      * 异常时触发 
  50.      * @param myWebsocket 
  51.      * @param throwable 
  52.      */  
  53.     @OnError  
  54.     public void onError(@PathParam("myWebsocket") String myWebsocket, Throwable throwable) {  
  55.         logger.info("Websocket Connection Exception:" + myWebsocket);  
  56.         logger.info(throwable.getMessage(), throwable);  
  57.         clients.remove(myWebsocket);  
  58.     }  
  59.   
  60.     /** 
  61.      * 关闭连接时触发 
  62.      * @param myWebsocket 
  63.      */  
  64.     @OnClose  
  65.     public void onClose(@PathParam("myWebsocket") String myWebsocket) {  
  66.         logger.info("Websocket Close Connection:" + myWebsocket);  
  67.         clients.remove(myWebsocket);  
  68.     }  
  69.   
  70.   
  71.     /** 
  72.      * 将数据传回客户端 
  73.      * 异步的方式 
  74.      * @param myWebsocket 
  75.      * @param message 
  76.      */  
  77.     public static void broadcast(String myWebsocket, String message) {  
  78.         if (clients.containsKey(myWebsocket)) {  
  79.             clients.get(myWebsocket).getAsyncRemote().sendText(message);  
  80.         } else {  
  81.             throw new NullPointerException("[" + myWebsocket +"]Connection does not exist");  
  82.         }  
  83.     }  
  84.   
  85. }  

然后添加相应的接受页面index.html:

[html]  view plain copy
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  2. <html>  
  3.     <head>  
  4.         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  5.         <meta http-equiv="X-UA-Compatible" content="IE=edge">  
  6.         <meta name="viewport" content="width=device-width, initial-scale=1">  
  7.           <script type="text/javascript" src="resources/jquery-1.8.3.min.js"></script>  
  8.      </head>     
  9. <body>  
  10.   
  11.    
  12. <script type="text/javascript">  
  13.  //测试controller是否可以进入  
  14. // ajaxDo("/activemq-client/index",null);  
  15.    
  16. // function ajaxDo(url,data){  
  17. //   $.ajax({  
  18. //          url:url ,  
  19. //          type: "post",  
  20. //          dataType: "json",  
  21. //          data: data,  
  22. //          success:function(result){  
  23. //             if(result.success){  
  24. //                 alert(result.data);  
  25. //             }else{  
  26. //                 alert(result.msg);  
  27. //             }  
  28. //          }  
  29. //      });  
  30. // }      
  31.   
  32.   
  33. //--------------------------------- webSocket ----------------------------------------------  
  34.   initSocket("user");  
  35.   initSocket("news");  
  36.   initSocket("client");  
  37.     
  38.   
  39. function initSocket(myWebsocket) {  
  40.       
  41.     var webSocket = null;  
  42.       
  43.     window.onbeforeunload = function () {  
  44.         //离开页面时的其他操作  
  45.     };  
  46.   
  47.     if (!window.WebSocket) {  
  48.         console("您的浏览器不支持websocket!");  
  49.         return false;  
  50.     }  
  51.   
  52.     var target = 'ws://' + window.location.host + "/activemq-client/websocket/"+myWebsocket;    
  53.             
  54.         if ('WebSocket' in window) {    
  55.             webSocket = new WebSocket(target);    
  56.         } else if ('MozWebSocket' in window) {    
  57.             webSocket = new MozWebSocket(target);    
  58.         } else {    
  59.             alert('WebSocket is not supported by this browser.');    
  60.             return;    
  61.         }    
  62.       
  63.       
  64.     // 收到服务端消息  
  65.     webSocket.onmessage = function (msg) {  
  66.             alert(msg.data);  
  67.         // 关闭连接  
  68.         webSocket.onclose();  
  69.         console.log(msg);  
  70.     };  
  71.   
  72.     // 异常  
  73.     webSocket.onerror = function (event) {  
  74.         console.log(event);  
  75.     };  
  76.   
  77.     // 建立连接  
  78.     webSocket.onopen = function (event) {  
  79.         console.log(event);  
  80.     };  
  81.   
  82.     // 断线  
  83.     webSocket.onclose = function () {  
  84.           
  85.         console.log("websocket断开连接");  
  86.     };  
  87. }  
  88.   
  89.   
  90. </script>  
  91.   
  92. </body>  
  93. </html>  

好了,websocket已经实现了,现在最重要的是我们要在哪儿监听哪些变动,在推送给前端的问题了,这里我监听了MQ消息队

列中的某个Queen,如果获取到消息就推送给前端展示,稍后我会把MQ的消息队列也写给大家看,做个参考。(当然你也可以

监听属于你自己的对象,主要是调用 WebsocketController.broadcast("client", jsonStr);第一个参数和前端的参数一

致,第二个参数是你想推送给前端的内容)。

[java]  view plain copy
  1. <span style="font-size:14px;"><span style="font-family:宋体;">package com.lwl.activemq.listener;  
  2.   
  3. import javax.jms.JMSException;  
  4. import javax.jms.Message;  
  5. import javax.jms.MessageListener;  
  6. import javax.jms.TextMessage;  
  7.   
  8. import org.apache.log4j.Logger;  
  9. import org.springframework.stereotype.Component;  
  10.   
  11. import com.alibaba.fastjson.JSON;  
  12. import com.lwl.activemq.domain.Client;  
  13. import com.lwl.activemq.controller.websocket.WebsocketController;  
  14.   
  15. @Component("clientPushListener")  
  16. public class ClientPushListener implements MessageListener {  
  17.      protected static final Logger logger = Logger.getLogger(ClientPushListener.class);  
  18.     @Override  
  19.     public void onMessage(Message message) {  
  20.          logger.info("[ClientPushListener.onMessage]:begin onMessage.");  
  21.             TextMessage textMessage = (TextMessage) message;  
  22.             try {  
  23.                 String jsonStr = textMessage.getText();  
  24.                 logger.info("[ClientPushListener.onMessage]:receive message is,"+ jsonStr);  
  25.                 if (jsonStr != null) {  
  26.                     Client info = JSON.parseObject(jsonStr, Client.class);  
  27.                     System.out.println("==============================接受到的客户信息 开始====================================");  
  28.                     System.out.println(info.toString());  
  29.                     System.out.println("==============================接受到的客户信息 结束====================================");  
  30.                     WebsocketController.broadcast("client", jsonStr);  
  31.                 }  
  32.             } catch (JMSException e) {  
  33.                 logger.error("[ClientPushListener.onMessage]:receive message occured an exception",e);  
  34.             }  
  35.             logger.info("[ClientPushListener.onMessage]:end onMessage.");  
  36.         }  
  37. }</span></span>  
转自: http://blog.csdn.net/LOVELONG8808/article/details/52277029

这篇关于Java Websocket实例【服务端与客户端实现全双工通讯】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1150242

相关文章

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

Qt中QGroupBox控件的实现

《Qt中QGroupBox控件的实现》QGroupBox是Qt框架中一个非常有用的控件,它主要用于组织和管理一组相关的控件,本文主要介绍了Qt中QGroupBox控件的实现,具有一定的参考价值,感兴趣... 目录引言一、基本属性二、常用方法2.1 构造函数 2.2 设置标题2.3 设置复选框模式2.4 是否

Java字符串处理全解析(String、StringBuilder与StringBuffer)

《Java字符串处理全解析(String、StringBuilder与StringBuffer)》:本文主要介绍Java字符串处理全解析(String、StringBuilder与StringBu... 目录Java字符串处理全解析:String、StringBuilder与StringBuffer一、St

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

springboot整合阿里云百炼DeepSeek实现sse流式打印的操作方法

《springboot整合阿里云百炼DeepSeek实现sse流式打印的操作方法》:本文主要介绍springboot整合阿里云百炼DeepSeek实现sse流式打印,本文给大家介绍的非常详细,对大... 目录1.开通阿里云百炼,获取到key2.新建SpringBoot项目3.工具类4.启动类5.测试类6.测

Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

《SpringBoot循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三

pytorch自动求梯度autograd的实现

《pytorch自动求梯度autograd的实现》autograd是一个自动微分引擎,它可以自动计算张量的梯度,本文主要介绍了pytorch自动求梯度autograd的实现,具有一定的参考价值,感兴趣... autograd是pytorch构建神经网络的核心。在 PyTorch 中,结合以下代码例子,当你

在Spring Boot中浅尝内存泄漏的实战记录

《在SpringBoot中浅尝内存泄漏的实战记录》本文给大家分享在SpringBoot中浅尝内存泄漏的实战记录,结合实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录使用静态集合持有对象引用,阻止GC回收关键点:可执行代码:验证:1,运行程序(启动时添加JVM参数限制堆大小):2,访问 htt

SpringBoot集成Milvus实现数据增删改查功能

《SpringBoot集成Milvus实现数据增删改查功能》milvus支持的语言比较多,支持python,Java,Go,node等开发语言,本文主要介绍如何使用Java语言,采用springboo... 目录1、Milvus基本概念2、添加maven依赖3、配置yml文件4、创建MilvusClient

浅析Java中如何优雅地处理null值

《浅析Java中如何优雅地处理null值》这篇文章主要为大家详细介绍了如何结合Lambda表达式和Optional,让Java更优雅地处理null值,感兴趣的小伙伴可以跟随小编一起学习一下... 目录场景 1:不为 null 则执行场景 2:不为 null 则返回,为 null 则返回特定值或抛出异常场景