http://www.blogjava.net/qbna350816/archive/2016/07/24/431302.html

https://segmentfault.com/q/1010000004955225

https://www.cnblogs.com/interdrp/p/4091056.html

框架是workerman
socket.io

使用四种框架分别实现百万websocket常连接的服务器

首先我们查看一下ServerEndpoint类源码:

  1. @Retention(value = RetentionPolicy.RUNTIME)
  2. @Target(value = {ElementType.TYPE})
  3. public @interface ServerEndpoint {
  4. public String value();
  5. public String[] subprotocols() default {};
  6. public Class<? extends Decoder>[] decoders() default {};
  7. public Class<? extends Encoder>[] encoders() default {};
  8. public Class<? extends ServerEndpointConfig.Configurator> configurator() default ServerEndpointConfig.Configurator.class;
  9. }

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

代码示例:可以指定为自己的一个消息对象

  1. package com.zlxls.information;
  2. import com.alibaba.fastjson.JSON;
  3. import com.common.model.SocketMsg;
  4. import javax.websocket.EncodeException;
  5. import javax.websocket.Encoder;
  6. import javax.websocket.EndpointConfig;
  7. /**
  8. * 配置WebSocket解码器,用于发送请求的时候可以发送Object对象,实则是json数据
  9. * sendObject()
  10. * @ClassNmae:ServerEncoder
  11. * @author zlx-雄雄
  12. * @date    2017-11-3 15:47:13
  13. *
  14. */
  15. public class ServerEncoder implements Encoder.Text<SocketMsg> {
  16. @Override
  17. public void destroy() {
  18. // TODO Auto-generated method stub
  19. }
  20. @Override
  21. public void init(EndpointConfig arg0) {
  22. // TODO Auto-generated method stub
  23. }
  24. @Override
  25. public String encode(SocketMsg socketMsg) throws EncodeException {
  26. try {
  27. return JSON.toJSONString(socketMsg);
  28. } catch (Exception e) {
  29. // TODO Auto-generated catch block
  30. e.printStackTrace();
  31. return "";
  32. }
  33. }
  34. }

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.

  1. package com.zlxls.information;
  2. import com.common.model.SocketMsg;
  3. import javax.websocket.DecodeException;
  4. import javax.websocket.Decoder;
  5. import javax.websocket.EndpointConfig;
  6. /**
  7. * 解码器执,它读入Websocket消息,然后输出java对象
  8. * @ClassNmae:ServerDecoder
  9. * @author zlx-雄雄
  10. * @date    2017-11-11 9:12:09
  11. *
  12. */
  13. public class ServerDecoder implements Decoder.Text<SocketMsg>{
  14. @Override
  15. public void init(EndpointConfig ec){}
  16. @Override
  17. public void destroy(){}
  18. @Override
  19. public SocketMsg decode(String string) throws DecodeException{
  20. // Read message...
  21. return new SocketMsg();
  22. }
  23. @Override
  24. public boolean willDecode(String string){
  25. // Determine if the message can be converted into either a
  26. // MessageA object or a MessageB object...
  27. return false;
  28. }
  29. }

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:

  1. /**
  2. * 发生错误是调用方法
  3. * @param t
  4. * @throws Throwable
  5. */
  6. @OnError
  7. public void onError(Throwable t) throws Throwable {
  8. System.out.println("错误: " + t.toString());
  9. }

为一个注解式的端点指定一个处理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.

代码示例:

  1. package com.zlxls.information;
  2. import javax.servlet.http.HttpSession;
  3. import javax.websocket.HandshakeResponse;
  4. import javax.websocket.server.HandshakeRequest;
  5. import javax.websocket.server.ServerEndpointConfig;
  6. import javax.websocket.server.ServerEndpointConfig.Configurator;
  7. /**
  8. * 由于websocket的协议与Http协议是不同的,
  9. * 所以造成了无法直接拿到session。
  10. * 但是问题总是要解决的,不然这个websocket协议所用的场景也就没了
  11. * 重写modifyHandshake,HandshakeRequest request可以获取httpSession
  12. * @ClassNmae:GetHttpSessionConfigurator
  13. * @author zlx-雄雄
  14. * @date    2017-11-3 15:47:13
  15. *
  16. */
  17. public class GetHttpSessionConfigurator extends Configurator{
  18. @Override
  19. public void modifyHandshake(ServerEndpointConfig sec,HandshakeRequest request, HandshakeResponse response) {
  20. HttpSession httpSession=(HttpSession) request.getHttpSession();
  21. sec.getUserProperties().put(HttpSession.class.getName(),httpSession);
  22. }
  23. }
  1. @OnOpen
  2. public void open(Session s, EndpointConfig conf){
  3. HandshakeRequest req = (HandshakeRequest) conf.getUserProperties().get("sessionKey");
  4. }

@ServerEndpoint(

value = "/myendpoint",

configurator=GetHttpSessionConfigurator.class

)

不过要特别说一句:

HandshakeRequest req = (HandshakeRequest) conf.getUserProperties().get("sessionKey");  目前获取到的是空值。会报错:java.lang.NullPointerException,这个错误信息,大家最熟悉不过了。

原因是:请求头里面并没有把相关的信息带上

这里就需要实现一个监听,作用很明显:将所有request请求都携带上httpSession,这样就可以正常访问了

说明:注解非常简单可以直接使用注解@WebListener,也可以再web.xml配置监听

    1. package com.zlxls.information;
    2. import javax.servlet.ServletRequestEvent;
    3. import javax.servlet.ServletRequestListener;
    4. import javax.servlet.annotation.WebListener;
    5. import javax.servlet.http.HttpServletRequest;
    6. /**
    7. * http://www.cnblogs.com/zhuxiaojie/p/6238826.html
    8. * 配置监听器,将所有request请求都携带上httpSession
    9. * 用于webSocket取Session
    10. * @ClassNmae:RequestListener
    11. * @author zlx-雄雄
    12. * @date    2017-11-4 11:27:33
    13. *
    14. */
    15. @WebListener
    16. public class RequestListener implements ServletRequestListener {
    17. @Override
    18. public void requestInitialized(ServletRequestEvent sre)  {
    19. //将所有request请求都携带上httpSession
    20. ((HttpServletRequest) sre.getServletRequest()).getSession();
    21. }
    22. public RequestListener() {}
    23. @Override
    24. public void requestDestroyed(ServletRequestEvent arg0)  {}
    25. }

java websocket @ServerEndpoint注解说明的更多相关文章

  1. java websocket学习

    引言: websocket,webservice傻傻分不清楚,都觉得是很高深的东西,理解中的webservice是一种协议,通信协议,类似http协议的那种,比如使用webservice协议调后台接口 ...

  2. java websocket 简单使用【案例】

    现很多网站为了实现即时通讯,所用的技术都是轮询(polling).轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发 出HTTP request,然后由服务器返回最新的数据给客服端的浏览器.这种 ...

  3. Websocket @serverendpoint 404

    今天写一个前后端交互的websocket , 本来写着挺顺利的,但测试的时候蒙了,前端websocket发的连接请求竟然连接不上 返回状态Status 报了个404 ,然后看后台onError方法也没 ...

  4. Java WebSocket实现简易聊天室

    一.Socket简介 Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求.Socket的英文原义是“孔”或“插座”,作为UNI ...

  5. java中的注解(Annotation)

    转载:https://segmentfault.com/a/1190000007623013 简介 注解,java中提供了一种原程序中的元素关联任何信息.任何元素的途径的途径和方法. 注解是那些插入到 ...

  6. java @param参数注解

    注解,@param是参数的解释.如/***@param s 这里表示对s的文字说明,描述 */ public void aa(String s){}一般java中@表示注解,解释一个方法,类,属性的作 ...

  7. JAVA高级特性 - 注解

    注解是插入到代码中用于某种工具处理的标签.这些标签可以在源码层次上进行操作,或者可以处理编译器将其纳入到注解类文件中. 注解不会改变对程序的编译方式.Java编译器会对包含注解和不包含注解的代码生成相 ...

  8. 使用Jetty搭建Java Websocket Server,实现图像传输

    https://my.oschina.net/yushulx/blog/298140 How to Implement a Java WebSocket Server for Image Transm ...

  9. java中的注解总结

    1. 什么是注解 注解是java5引入的特性,在代码中插入一种注释化的信息,用于对代码进行说明,可以对包.类.接口.字段.方法参数.局部变量等进行注解.注解也叫元数据(meta data).这些注解信 ...

随机推荐

  1. asp.net web api的源码

    从安装的NuGet packages逆向找回去 <package id="Microsoft.AspNet.WebApi.Core" version="5.2.7& ...

  2. [AHOI2008]上学路线

    题意:给定一个无向图,删除某些边有一定的代价,要求删掉使得最短路径减小,求最小代价. 首先要spfa求出起点到各个点的最短距离.对于一条权值为w,起点为i,终点为j的边,设dis[k]为起点到k点的距 ...

  3. sql批处理(batch)的简单使用

    批处理指的是一次操作中执行多条SQL语句,相比于一次一次执行效率会提高很多 批处理主要是分两步: 将要执行的SQL语句保存 执行SQL语句 Statement和PreparedStatement都支持 ...

  4. Mongodb 命令及 PyMongo 库的使用

    1. PyMongo import pymongo 1. 初始化 Mongo 客户端 client=pymongo.MongoClient(mongodb://10.85.39.45:8188,10. ...

  5. hiho一下 第二周 trie树

    Trie树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路 ...

  6. bzoj1058: [ZJOI2007]报表统计 stl xjbg

    小Q的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小Q希望可以帮妈妈分担一些工作,作为她的生日礼物之一.经过仔细观察,小Q发现统计一张报表实际上是维护一个可能为负数的整数数列,并且 ...

  7. 使用方法拦截机制在不修改原逻辑基础上为 spring MVC 工程添加 Redis 缓存

    首先,相关文件:链接: https://pan.baidu.com/s/1H-D2M4RfXWnKzNLmsbqiQQ 密码: 5dzk 文件说明: redis-2.4.5-win32-win64.z ...

  8. poj1191 棋盘分割。 dp

    连接:http://poj.org/problem?id=1191 思路:额,其实就是直接搞记录一下就可以了. #include <stdio.h> #include <string ...

  9. Spring的注解@Qualifier(二十五)

    转载:https://www.cnblogs.com/smileLuckBoy/p/5801678.html 近期在捯饬spring的注解,现将遇到的问题记录下来,以供遇到同样问题的童鞋解决~ 先说明 ...

  10. [批处理]Oracle启动助手

    前段日子开始学Oracle数据库,但是由于Oracle数据库的服务启动时间很长 所以机房的里面所有电脑的Oracle服务全部是被禁用的 所以每次上机使用的时候都要先进服务管理,然后把禁用更改为手动模式 ...