websocket之参数传递和依赖注⼊
背景
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(LogSocket.class);
private final int DEFAULT_SSH_PORT = 22;
//websocket中不能使⽤注解进⾏依赖注⼊
//Resource
//private OnlineService onlineService;
private OnlineService onlineService = (OnlineService) CurrentWebApplicationContext().getBean("onlineService");
/**
* 连接建⽴成功调⽤的⽅法
*
* @param session
*            可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
*/
@OnOpen
public 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 " + LogpathByModuleName(
@ServerEndpoint("/websocket/{moduleName}/{serverIp}")
public class LogSocket {
// 与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
private Process process;
private InputStream inputStream;
private static Logger logger = Logger(LogSocket.class);
private final int DEFAULT_SSH_PORT = 22;
//websocket中不能使⽤注解进⾏依赖注⼊
/
/Resource
//private OnlineService onlineService;
private OnlineService onlineService = (OnlineService) CurrentWebApplicationContext().getBean("onlineService");
/**
* 连接建⽴成功调⽤的⽅法
*
* @param session
*            可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
*/
@OnOpen
public 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 " + LogpathByModuleName(
参数传递
其实这个问题不难,主要是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>websocket和socket
* <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 {
}
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(CurrentWebApplicationContext().getBean)还是可以的。显⽰加载时,同时需要在spring的配置⽂件中显⽰地配置ben: <bean id="onlineService" class="com.wangyin.ebl.service.impl.OnlineServiceImpl"></bean>  。问题总算是解决
了,但是还是没搞明⽩原因,等过段时间有空了再慢慢思考吧。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。