转载

入门 websocket

websocket 的概念如下链接:

点击这里

Java Websocket

如果要使用 Java 搭建一个 websocket 服务的话,在 J2EE7 当中给出了 websocket 的规范,需要创建一个 web 项目,并且在 pom 当中引入 jar:

<dependency>  <groupId>javax.websocket</groupId>  <artifactId>javax.websocket-api</artifactId>  <version>1.1</version> </dependency> 

JSR 356 是 websocket 的规范说明,并且也是 JavaEE7 的一部分,首先了解下几个概念。

Endpoint

Endpoint 代表可以处理 websocket 当中的对话。一般有两种方式可以创建 Endpoint:

  • 基于注解
  • 基于继承
@ServerEndpoint("/wstest") public class Test1EndPoint {   @OnClose  public void out(Session session, CloseReason closeReason) {  }   @OnOpen  public void onOpen(Session session, EndpointConfig config) {  }   @OnMessage  public void onMessage(String message, Session session) {  }      @OnError  public void onError(Session session, Throwable thr) {  } }    public class TestEndPoint extends Endpoint {   @Override  public void onOpen(Session session, EndpointConfig arg1) {  }   @Override  public void onClose(Session session, CloseReason closeReason) {   super.onClose(session, closeReason);  }   @Override  public void onError(Session session, Throwable thr) {   super.onError(session, thr);  } } 

Session

Session 表示 EndPoint 与 Client 之间的一系列交互。对于与一个 EndPoint 交互的每个 Client,有唯一一个 Session 实例表示该交互。

从上面的代码示例当中,我们可以看到 Session 的生命周期,onOpen -> onMessage -> onClose。

注解 ServerEndpoint

看下 ServerEndpoint 的详细代码:

@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface ServerEndpoint {      //表示映射的地址,必须以‘/’开头,是否以‘/’结尾都行     public String value();      public String[] subprotocols() default {};      //解码器,从client来的消息先走解码器     public Class<? extends Decoder>[] decoders() default {};      //编码器,从server返回的消息走编码器     public Class<? extends Encoder>[] encoders() default {};   //ServerEndpointConfig 的配置信息,可以配置握手协议等信息     public Class<? extends ServerEndpointConfig.Configurator> configurator() default ServerEndpointConfig.Configurator.class; } 

再来看 decoders 的几个基本用法:

public class MyDecoder implements Decoder.Text<JSONObject> {   @Override  public void init(EndpointConfig config) {   System.out.println("====MyDecoder====");  }   @Override  public void destroy() {   }   @Override  public JSONObject decode(String s) throws DecodeException {   System.out.println("decode====" + s);   return JSONObject.fromObject(s);  }   @Override  public boolean willDecode(String s) {   System.out.println("willDecode====" + s);   return true;  } }   @ServerEndpoint(value = "/testws", decoders=MyDecoder.class) public class WsServiceEndpoint {   @OnClose  public void out(Session session, CloseReason closeReason) {  }   @OnOpen  public void onOpen(Session session, EndpointConfig config) {   System.out.println("onOpen======");  }   @OnMessage  public void onMessage(JSONObject message, Session session) {   try {    System.out.println(message);    session.getBasicRemote().sendText("go");   } catch (IOException e) {    e.printStackTrace();   }  }  } 

代码比较简单,不多解释,编码也是如此。

ServerEndpoint 的 value 属性,可以类似于 spring mvc 当中的 pathvariable :

@ServerEndpoint("/bookings/{guest-id}") public class BookingServer {  @OnMessage  public void processBookingRequest(  @PathParam("guest-id") String guestID, String message,  Session session) {  // process booking from the given guest here  } } 

消息类型

从 Decoder 的几个接口可以看出来,websocket 可以处理的数据类型:

  • Binary(ByteBuffer)
  • BinaryStream(InputStream)
  • Text(String)
  • TextStream(Reader)

部署

有两种方式部署 websocket:

  • 使用 war 包,放到 web 容器当中
  • 使用 ServerContainer 部署编程式的 EndPoint

使用 war 包的情况,web 容器会自动扫描:

  1. 实现 javax.websocket.ServerApplicationConfig 的类
  2. 有 javax.websocket.server.ServerEndpoint 注解的类
  3. 实现 javax.websocket.Endpoint 的类

代码如下:

public class MyApplicationConfigOne implements ServerApplicationConfig {     public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> endpointClasses);         Set<Class<? extends Endpoint>> s = new HashSet<Class<? extends Endpoint>>;         s.add(ProgrammaticEndpointOne.class);         return s;     }      public Set<Class> getAnnotatedEndpointClasses(Set<Class<?>> scanned);        Set<Class<?>> s = new HashSet<Class<?>>;         s.add(AnnotatedEndpointOne.class);         return s;     } } 

【参考资料】

  1. https://tyrus.java.net/documentation/1.5/index/getting-started.html
  2. http://www.code123.cc/468.html

—EOF—

原文  http://renchx.com/websocket
正文到此结束
Loading...