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

相关文章

SpringBoot启动报错的11个高频问题排查与解决终极指南

《SpringBoot启动报错的11个高频问题排查与解决终极指南》这篇文章主要为大家详细介绍了SpringBoot启动报错的11个高频问题的排查与解决,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一... 目录1. 依赖冲突:NoSuchMethodError 的终极解法2. Bean注入失败:No qu

Java异常架构Exception(异常)详解

《Java异常架构Exception(异常)详解》:本文主要介绍Java异常架构Exception(异常),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. Exception 类的概述Exception的分类2. 受检异常(Checked Exception)

使用Java实现通用树形结构构建工具类

《使用Java实现通用树形结构构建工具类》这篇文章主要为大家详细介绍了如何使用Java实现通用树形结构构建工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录完整代码一、设计思想与核心功能二、核心实现原理1. 数据结构准备阶段2. 循环依赖检测算法3. 树形结构构建4. 搜索子

Spring定时任务只执行一次的原因分析与解决方案

《Spring定时任务只执行一次的原因分析与解决方案》在使用Spring的@Scheduled定时任务时,你是否遇到过任务只执行一次,后续不再触发的情况?这种情况可能由多种原因导致,如未启用调度、线程... 目录1. 问题背景2. Spring定时任务的基本用法3. 为什么定时任务只执行一次?3.1 未启用

MySQL多列IN查询的实现

《MySQL多列IN查询的实现》多列IN查询是一种强大的筛选工具,它允许通过多字段组合快速过滤数据,本文主要介绍了MySQL多列IN查询的实现,具有一定的参考价值,感兴趣的可以了解一下... 目录一、基础语法:多列 IN 的两种写法1. 直接值列表2. 子查询二、对比传统 OR 的写法三、性能分析与优化1.

在C#中调用Python代码的两种实现方式

《在C#中调用Python代码的两种实现方式》:本文主要介绍在C#中调用Python代码的两种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#调用python代码的方式1. 使用 Python.NET2. 使用外部进程调用 Python 脚本总结C#调

springboot报错Invalid bound statement (not found)的解决

《springboot报错Invalidboundstatement(notfound)的解决》本文主要介绍了springboot报错Invalidboundstatement(not... 目录一. 问题描述二.解决问题三. 添加配置项 四.其他的解决方案4.1 Mapper 接口与 XML 文件不匹配

MySQL新增字段后Java实体未更新的潜在问题与解决方案

《MySQL新增字段后Java实体未更新的潜在问题与解决方案》在Java+MySQL的开发中,我们通常使用ORM框架来映射数据库表与Java对象,但有时候,数据库表结构变更(如新增字段)后,开发人员可... 目录引言1. 问题背景:数据库与 Java 实体不同步1.1 常见场景1.2 示例代码2. 不同操作

SpringBoot使用OkHttp完成高效网络请求详解

《SpringBoot使用OkHttp完成高效网络请求详解》OkHttp是一个高效的HTTP客户端,支持同步和异步请求,且具备自动处理cookie、缓存和连接池等高级功能,下面我们来看看SpringB... 目录一、OkHttp 简介二、在 Spring Boot 中集成 OkHttp三、封装 OkHttp

JavaScript错误处理避坑指南

《JavaScript错误处理避坑指南》JavaScript错误处理是编程过程中不可避免的部分,它涉及到识别、捕获和响应代码运行时可能出现的问题,本文将详细给大家介绍一下JavaScript错误处理的... 目录一、错误类型:三大“杀手”与应对策略1. 语法错误(SyntaxError)2. 运行时错误(R