建站不止于增删改查,还有很多很有魅力的地方。对于通信聊天这块已经青睐好久了,前段时间在做的j2ee项目运用到Spring+SpringMVC+MyBatis的框架集合,是关于一个社交平台的网站,类似于facebook,twitter,微博等。在做完基本的CURD(例如评论模块)后,开始研究网站通信并应用于项目中。
提到通信,大家都知道Socket。确实,运用Socket能在服务器与客户端之间建立一个数据交换的通道。之前用java SE写过的Socket通信 —模拟用户登录简单地实现了服务器与客户端传送消息。但是再细想一下,如果要在项目中实现网页聊天功能,把Socket用到j2ee项目中,或许就没那么简单了。这时转向baidu与google寻找答案,原来,有WebSocket这套协议,关于WebSocket,来自IBM这两篇文章已经介绍地很详细了:WebSocket 实战,使用 HTML5 WebSocket 构建实时 Web 应用。
Spring Framework 4 includes a new spring-websocket module with comprehensive WebSocket support. It is compatible with the Java WebSocket API standard (JSR-356) and also provides additional value-add as explained in the rest of the introduction.来自Spring官方文档:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html
非常庆幸的是,在Spring 4.0以上开始支持WebSocket了,并给出一套API供开发者使用。
下面就开始讲解WebSocket如何应用于SSM框架,说明其中的工作原理,并在最后给出网页聊天效果图。
一.客户端(js)新建WebSocket对象,指定要进行握手连接的服务器地址:
讲解:
在新建WebSocket对象时,给出的参数字符串中ws表明协议使用的是WebSocket协议,socketPath就是要连接的服务器地址,在下文会进一步说明。
如果成功连接,就会执行onopen;如果连接失败,就会执行onerror;如果连接断开,就会执行onclose,如果服务器有消息发送过来,就会执行onmessage。
二.服务端导入Spring WebSocket相关jar依赖:
讲解:
关于SpringMVC,Mybatis的jar包依赖就不列出来了。本文重点为如何在SSM框架上应用WebSocket。
三.服务器添加WebSocket服务:
讲解:
1.首先说说上文提到的客户端指定握手连接的服务器地址:在jsp中定义socketPath为 String socketPath = request.getServerName()+”:”+request.getServerPort()+path+”/”;其中path的定义为 String path = request.getContextPath();相信做SSM项目的你们都很清楚了。getServerName()先得到服务器机的ip地址;getServerPort()得到相应的端口号;getContextPath()得到的是上下文路径,其实就是发布了的项目文件夹的文件名,我发布了的项目文件夹名为web,在这个文件夹下有META-INF,WEB-INF和一个默认的index.jsp,WEB-INF内的页面是不允许外界访问的,所以当我们要访问里面的jsp页面时唯一的方法就是通过springMVC的映射,不是吗?最后我把项目发布到远程服务器上并通过外网进行测试连接到的路径为: “ws://139.129.47.176:8089/web//ws”
2.我在139.129.47.176:8089/web/后面加上一些事先规定好的映射匹配字符就能访问页面。因此我总结的就是:139.129.47.176:8089/web/就能得到我Tomcat容器下的SpringIOC容器,里面都是我写好的controller,service接口对象。
3.注意到上面代码中有@Component注解,已经给出注释了,就是相当于告诉SpringMVC这是SpringIOC容器下管理的类,和@Controller注解其实是一样的,通过139.129.47.176:8089/web/能访问到Controller并做映射,通过139.129.47.176:8089/web/同样可以访问MyWebSocketConfig这个类在SpringIOC下的对象,从而服务端进行WebSocket服务。
4.写到这里,相信熟悉SSM运行流程的你们都应该懂WebSocket的路径了。
5.在上面的代码中出现到MyWebSocketHandler handler;与new MyHandShakeInterceptor()。其中handler规定了服务端WebSocket的处理。而MyHandShakeInterceptor是客户端与服务端握手连接前后拦截器。
四.握手拦截器MyHandShakeInterceptor:
讲解:
1.拦截的概念就是在一个操作前,与在这个操作后的两个时间切面将要进行的动作。
2.客户端与服务端握手连接前将键名”uid“,值为用户id的这个键值对加入到指定参数map中。为服务器建立与相应客户端连接的WebSocketSession打下基础。
五.MyWebSocketHandler,WebSocket处理器:
讲解:
1.这个处理器的@Component注解就是告诉Spring将这个类的对象注入到IOC容器中,这样在MyWebSocketConfig中才可以通过@Autowired将其自动装载,进而使用。
2.简单地说说这个处理器,握手实现连接后会执行afterConnectionEstablished()方法,这个方法就是将握手连接后为与客户端实现通信而建立的WebSocketSession加入到静态变量userSocketSessionMap中。
3.当客户端断开连接后会执行afterConnectionClosed(),这时需要将与客户端对应的WebSocketSession从userSocketSessionMap中移除,原因已在注释中给出,简直血的教训,调试了好久才发现….
4.客户端一有消息发送至服务器就会自动执行handleMessage()方法,其中Message msg=new Gson().fromJson(webSocketMessage.getPayload().toString(),Message.class);将JSON形式的数据解析成Message对象,Message的定义稍后给出。
5.服务器发送信息至客户端只需要一句话,就是通过在服务器中WebSocketSession的sendMessage()方法,详情都在代码中。
六.客户端发送信息与接受信息:
发送:
接收:
讲解:
- 发送信息时需要将对象转换为JSON形式的数据,因为服务器本来就是将JSON数据转换成对象的。
- 客户端接收信息时将数据解析成JSON形式后就能在js中获取相应的数据。
七.Message类: