websocket之参数传递和依赖注入

来源:互联网 发布:套接字编程 编辑:程序博客网 时间:2024/05/02 00:50

背景

      WebSocket协议是一种基于TCP的新协议。不同于http仅能实现单向通信,它实现了浏览器与服务器的全双工通信,因此可以被应用在bs架构的聊天系统、远程日志查看等系统中。websocket在建立连线时仅需要进行一次“握手”就能建立“长连接”,也就是浏览器发出websocket连线请求,然后服务器发出回应即可。目前chrome、firefox和IE10+等主流浏览器都支持Websocket. 

 问题

         由于项目需要,最近在做一个如下的自主上线系统。为了便于尽早发现上线过程中的问题,该系统中有一个在web页面上实时显示服务日志的功能,我在通过websocket实现这个功能的过程中遇到了2个问题:websocket建立连接时需要传递参数(例如服务器ip,项目名称,日志文件位置等)进去;需要注入service 层的类,以便在onOpen()方法中进行数据查询和业务处理。百度谷歌一顿搜索后,发现这两个问题还挺有共性的,很多人都在问,但是靠谱的答案却比较少见。通过查看源码和各种折腾,最后还是解决了这些问题,做个总结。

      

解决方案

先上解决方案:
        @ServerEndpoint("/websocket/{moduleName}/{serverIp}")public class LogSocket {// 与某个客户端的连接会话,需要通过它来给客户端发送数据private Session session;private Process process;private InputStream inputStream;private static Logger logger = Logger.getLogger(LogSocket.class);private final int DEFAULT_SSH_PORT = 22;//websocket中不能使用注解进行依赖注入//Resource//private OnlineService onlineService;private OnlineService onlineService = (OnlineService) ContextLoader.getCurrentWebApplicationContext().getBean("onlineService");/** * 连接建立成功调用的方法 *  * @param session *            可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据 */@OnOpenpublic void onOpen(@PathParam("moduleName") String moduleName,@PathParam("serverIp") String serverIp, Session session) {this.session = session;webSocketSet.add(this); // 加入set中logger.info("日志开始");logger.info("websocket:" + moduleName);System.out.println("websocket:" + moduleName);String command = "tail -100f " + onlineService.getLogpathByModuleName(moduleName.trim(), serverIp.trim());


参数传递

其实这个问题不难,主要是websocket的应用比较少,自己平时也少有看源码的习惯。先来看看websocket的OnOpen注解的源码,突破点已用粗体标出了。

package javax.websocket;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * This method level annotation can be used to decorate a Java method that wishes to be called when a new * web socket session is open. * * <p>The method may only take the following parameters:- * <ul> * <li>optional {@link Session} parameter</li> * <li>optional {@link EndpointConfig} parameter</li> * <li>Zero to n String parameters annotated with the {@link javax.websocket.server.PathParam} annotation.</li> * </ul> * * <p>The parameters may appear in any order. * * @author dannycoward */@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface OnOpen {}


使用@ServerEndpoint注解将参数拼接在建立连接的url上(@ServerEndpoint("/websocket/{moduleName}/{serverIp}")),使用@PathParam 注解进行参数获取( onOpen(@PathParam("moduleName") String moduleName,@PathParam("serverIp") String serverIp, Session session))。

依赖注入

起初是通过注解的方式注入的依赖,运行时报空指针,没有注入进去。一番折腾之后,发现虽然使用注解无法注入,但是使用显示的方式加载bean(ContextLoader.getCurrentWebApplicationContext().getBean)还是可以的。显示加载时,同时需要在spring的配置文件中显示地配置ben: <bean id="onlineService" class="com.wangyin.ebl.service.impl.OnlineServiceImpl"></bean>  。问题总算是解决了,但是还是没搞明白原因,等过段时间有空了再慢慢思考吧。


0 0
原创粉丝点击