websocket@ServerEndpoint注解说明
⾸先我们查看⼀下ServerEndpoint类源码:
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = {ElementType.TYPE})
public @interface ServerEndpoint {
public String value();
public String[] subprotocols() default {};
public Class<? extends Decoder>[] decoders() default {};
public Class<? extends Encoder>[] encoders() default {};
public Class<? extends ServerEndpointConfig.Configurator> configurator() default ServerEndpointConfig.Configurator.class;
}
Encoders and Decoders(编码器和解码器):
WebSocket Api 提供了encoders 和 decoders⽤于 Websocket Messages 与传统java 类型之间的转换
An encoder takes a Java object and produces a representation that can be transmitted as a WebSocket message;
编码器输⼊java对象,⽣成⼀种表现形式,能够被转换成Websocket message
for example, encoders typically produce JSON, XML, or binary representations.
例如:编码器通常⽣成json、XML、⼆进制三种表现形式
A decoder performs the reverse function; it reads a WebSocket message and creates a Java object.
解码器执⾏相反的⽅法,它读⼊Websocket消息,然后输出java对象
编码器编码:
looks for an encoder that matches your type and uses it to convert the object to a WebSocket message.
利⽤RemoteEndpoint.Basic 或者RemoteEndpoint.Async的sendObject(Object data)⽅法将对象作为消息发送,容器寻⼀个符合此对象的编码器,
利⽤此编码器将此对象转换成Websocket message
代码⽰例:可以指定为⾃⼰的⼀个消息对象
import com.alibaba.fastjson.JSON;
del.SocketMsg;
import javax.websocket.EncodeException;
import javax.websocket.Encoder;
import javax.websocket.EndpointConfig;
/**
* 配置WebSocket解码器,⽤于发送请求的时候可以发送Object对象,实则是json数据
* sendObject()
* @ClassNmae:ServerEncoder
* @author zlx-雄雄
* @date 2017-11-3 15:47:13
*
*/
public class ServerEncoder implements Encoder.Text<SocketMsg> {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void init(EndpointConfig arg0) {
// TODO Auto-generated method stub
}
@Override
public String encode(SocketMsg socketMsg) throws EncodeException {
try {
JSONString(socketMsg);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "";
}
}
}
Then, add the encodersparameter to the ServerEndpointannotation as follows:
@ServerEndpoint(
value = "/myendpoint",
encoders = { ServerEncoder.class, ServerEncoder1.class }
)
解码器解码:
Decoder.Binary<T>for binary messages
These interfaces specify the willDecode and decode methods.
the container calls the method annotated with @OnMessage that takes your custom Java type as a parameter if this method exists.
del.SocketMsg;
import javax.websocket.DecodeException;
import javax.websocket.Decoder;
import javax.websocket.EndpointConfig;
/**
* 解码器执,它读⼊Websocket消息,然后输出java对象
* @ClassNmae:ServerDecoder
* @author zlx-雄雄
* @date 2017-11-11 9:12:09
*
*/
public class ServerDecoder implements Decoder.Text<SocketMsg>{
@Override
public void init(EndpointConfig ec){}
@Override
public void destroy(){}
@Override
public SocketMsg decode(String string) throws DecodeException{
//
return new SocketMsg();
}
@Override
public boolean willDecode(String string){
// Determine if the message can be converted into either a
// MessageA object or a
return false;
}
}
Then, add the decoderparameter to the ServerEndpointannotation as follows:
@ServerEndpoint(
value = "/myendpoint",
encoders = { ServerEncoder.class, ServerEncoder1.class },
decoders = {ServerDecoder.class }
)
处理错误:
To designate a method that handles errors in an annotated WebSocket endpoint, decorate it with @OnError:
/**
* 发⽣错误是调⽤⽅法
* @param t
* @throws Throwable
*/
@OnError
public void onError(Throwable t) throws Throwable {
System.out.println("错误: " + t.toString());
}
为⼀个注解式的端点指定⼀个处理error的⽅法,为此⽅法加上@OnError注解:
This method is invoked when there are connection problems, runtime errors from message handlers, or conversion errors when decoding messages.
当出现连接错误,运⾏时错误或者解码时转换错误,该⽅法才会被调⽤
指定端点配置类:
The Java API for WebSocket enables you to configure how the container creates server endpoint instances.
Websocket的api允许配置容器合适创建server endpoint 实例
You can provide custom endpoint configuration logic to:
Access the details of the initial HTTP request for a WebSocket connection
Perform custom checks on the OriginHTTP header
Modify the WebSocket handshake response
Choose a WebSocket subprotocol from those requested by the client
Control the instantiation and initialization of endpoint instances
To provide custom endpoint configuration logic, you extend the ServerEndpointConfig.Configurator class and override some of its methods.继承ServerEndpointConfig.Configurator 类并重写⼀些⽅法,来完成custom endpoint configuration 的逻辑代码
In the endpoint class, you specify the configurator class using the configurator parameter of the ServerEndpoint annotation.
代码⽰例:
package com.zlxls.information;
import javax.servlet.http.HttpSession;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
import javax.websocket.server.ServerEndpointConfig.Configurator;
/**
* 由于websocket的协议与Http协议是不同的,
* 所以造成了⽆法直接拿到session。
* 但是问题总是要解决的,不然这个websocket协议所⽤的场景也就没了
* 重写modifyHandshake,HandshakeRequest request可以获取httpSession
* @ClassNmae:GetHttpSessionConfigurator
* @author zlx-雄雄
* @date 2017-11-3 15:47:13
*
*/
public class GetHttpSessionConfigurator extends Configurator{
@Override
public void modifyHandshake(ServerEndpointConfig sec,HandshakeRequest request, HandshakeResponse response) {
HttpSession httpSession=(HttpSession) HttpSession();
}
}
@OnOpen
public void open(Session s, EndpointConfig conf){
HandshakeRequest req = (HandshakeRequest) UserProperties().get("sessionKey");
}
@ServerEndpoint(
value = "/myendpoint",
configurator=GetHttpSessionConfigurator.class
)
不过要特别说⼀句:
HandshakeRequest req = (HandshakeRequest) UserProperties().get("sessionKey"); ⽬前获取到的是空值。会报错:java.lang.NullPointerException,这个错误信息,⼤家最熟悉不过了。
原因是:请求头⾥⾯并没有把相关的信息带上
这⾥就需要实现⼀个监听,作⽤很明显:将所有request请求都携带上httpSession,这样就可以正常访问了
说明:注解⾮常简单可以直接使⽤注解@WebListener,也可以再l配置监听
package com.zlxls.information;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;
/**
* wwwblogs/zhuxiaojie/p/6238826.html
* 配置,将所有request请求都携带上httpSession
* ⽤于webSocket取Session
* @ClassNmae:RequestListener
websocket和socket* @author zlx-雄雄
* @date 2017-11-4 11:27:33
*
*/
@WebListener
public class RequestListener implements ServletRequestListener {
@Override
public void requestInitialized(ServletRequestEvent sre) {
//将所有request请求都携带上httpSession
((HttpServletRequest) ServletRequest()).getSession();
}
public RequestListener() {}
@Override
public void requestDestroyed(ServletRequestEvent arg0) {}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论