当前位置:   article > 正文

springboot+websocket+netty+getway+consul的集成_netty-websocket-spring-boot-starter nginx代理后 获取真实i

netty-websocket-spring-boot-starter nginx代理后 获取真实ip

一 配置集成

1.集成相关的jar

<dependency>
    <groupId>org.yeauty</groupId>
    <artifactId>netty-websocket-spring-boot-starter</artifactId>
    <version>0.9.5</version>
</dependency>
<!-- consul 注册组件 -->
        <dependency>
            <groupId>com.ecwid.consul</groupId>
            <artifactId>consul-api</artifactId>
        </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

netty-websocket-spring-boot-starter
这是个开源的框架。通过它,我们可以像spring-boot-starter-websocket一样使用注解进行开发,只需关注需要的事件(如OnMessage)。并且底层是使用Netty,当需要调参的时候只需要修改配置参数即可,无需过多的关心handler的设置。

2.配置webSocket
new一个ServerEndpointExporter对象,交给Spring容器,表示要开启WebSocket功能:

@Configuration
public class WebSocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在端点类上加上@ServerEndpoint、@Component注解,并在相应的方法上加上@OnOpen、@OnClose、@OnError、@OnMessage注解(不想关注某个事件可不添加对应的注解):

@ServerEndpoint(path = "/ws/lchl/demo/{arg}",host  ="${xxxpriv.websocket.host}", port = "${xxxpriv.websocket.port}")
public class WebSocketDemo {
    /** 记录当前在线连接数 */
    private static AtomicInteger onlineCount = new AtomicInteger(0);
    private Session session;
    private String id;


    private static ConcurrentHashMap<String, WebSocketDemo> webSocketSet = new ConcurrentHashMap<String, WebSocketDemo>();



    @SneakyThrows
    @OnOpen
    public void onOpen(Session session, HttpHeaders headers, @RequestParam MultiValueMap reqMap,
                       @RequestParam String orgnCode, @RequestParam String orgnName,
                       @RequestParam String userCode, @RequestParam String userName,
                       @RequestParam String token,
                       @PathVariable Map pathMap,@PathVariable(value = "arg") String id) throws IOException {

        this.session = session;
        this.id = id;//接收到发送消息的人员编号
        ResponseMessage result = new ResponseMessage();
        result.setMessage("连接成功");
        result.setCode("success");
        result.setMessage("{'connect':'true'}");
        this.sendMessage(JSONObject.toJSONString(result));

        for (int i = 0; i < 3; i++) {
            ResponseMessage result1 = new ResponseMessage();
            result.setMessage("处理进度为"+i+1+"/3;当前处理病人为王五\n" +
                    "处理失败医嘱\n" +
                    "[张三  葡萄糖注射液0.1%   库存量不足,执行失败!,\n" +
                    "张三   氯化钠注射液0.1%   未做皮试,执行失败!]\n" +
                    "[李三  氯化钠注射液0.1%   库存量不足,执行失败!]");
            Thread.sleep(3000);
            this.sendMessage(JSONObject.toJSONString(result));
        }
    }

    @OnClose
    public void onClose(Session session) throws IOException {
        System.out.println("one connection closed");
    }

    @OnError
    public void onError(Session session, Throwable throwable) {
        throwable.printStackTrace();
    }

    @OnMessage
    public void onMessage(Session session, String message) throws IOException {
        ResponseMessage result = new ResponseMessage();
        result.setMessage("XXXXXXXXXX");
        this.sendMessage(JSONObject.toJSONString(result));
    }

    @OnBinary
    public void onBinary(Session session, byte[] bytes) {
        for (byte b : bytes) {
            System.out.println(b);
        }
       // session.sendBinary(bytes);
    }

    @OnEvent
    public void onEvent(Session session, Object evt) {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
            switch (idleStateEvent.state()) {
                case READER_IDLE:
                    System.out.println("read idle");
                    break;
                case WRITER_IDLE:
                    System.out.println("write idle");
                    break;
                case ALL_IDLE:
                    System.out.println("all idle");
                    break;
                default:
                    break;
            }
        }
    }

    public void sendMessage(String message) throws IOException {
        this.session.sendText(message);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90

3.springboot2 集成webSocket+consul

xxxpri:
  host: 172.16.0.121 #应用ip
  server:
    port: 10050
    servlet:
      context-path: /websocket  #websocket
  application:
    name: websocket-application
    
    
    
    
websocket:
    name: websocket-server  #websocket程序名称 注册中心使用
    host: ${spring.cloud.client.ip-address} #websocket ip 地址
    port: 10051
    path: /ws
    consul:
      host: ${xxxpri.consul.host}
      port: ${xxxpri.consul.port}
      name: ${xxxpri.websocket.name}
      instance: ${xxxpri.websocket.name}-${xxxpri.websocket.host}-${xxxpri.websocket.port}
      healthCheckPath: ${server.servlet.context-path}/actuator/health
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

4.将websocket-server注册服务到Consul



    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(LchlApplication.class, args);
        //注册netty - websocket 服务到consul
        regWebSocketConsul(context);

     //   SpringApplication.run(LchlApplication.class, args);
        LOG.info("application started!");
    }



/**
 * websocket-server注册服务到Consul
 * @param context
 */
private static void regWebSocketConsul(ConfigurableApplicationContext context) {

    //consul 注册中心地址
    String consulEnable = context.getEnvironment().getProperty("xxxpri.consul.enabled");
    if (("true").equals(consulEnable.toLowerCase())){
        String consulAddress = context.getEnvironment().getProperty("xxxpri.websocket.consul.host") + ":" + context.getEnvironment().getProperty("xxxpri.websocket.consul.port");
        String websocketServerName = context.getEnvironment().getProperty("xxxpri.websocket.name");
        String websocketServerHost = context.getEnvironment().getProperty("xxxpri.websocket.host");
        String websocketServerPort = context.getEnvironment().getProperty("xxxpri.websocket.port");
        String websocketServerPath = context.getEnvironment().getProperty("xxxpri.websocket.path");
        String consulInstanceId = context.getEnvironment().getProperty("xxxpri.websocket.consul.instance");
        String springBootServerPort = context.getEnvironment().getProperty("xxxpri.server.port");
        String springBootServerContentPath = context.getEnvironment().getProperty("xxxpri.server.servlet.context-path");
        String checkUrl = "http://" + websocketServerHost + ":" + springBootServerPort
                + springBootServerContentPath+"/actuator/health";

        ConsulClient client = new ConsulClient(consulAddress);
        NewService newService = new NewService();
        newService.setId(consulInstanceId);
        List<String> tagList = new ArrayList<>();
        tagList.add("secure=false");
        tagList.add("contextPath=" + websocketServerPath);
        newService.setTags(tagList);
        newService.setName(websocketServerName);
        newService.setAddress(websocketServerHost);
        newService.setPort(Integer.valueOf(websocketServerPort));
        //服务检测,使用 spring-boot 项目
        NewService.Check serviceCheck = new NewService.Check();
        serviceCheck.setHttp(checkUrl);
        serviceCheck.setInterval("10s");
        newService.setCheck(serviceCheck);
        client.agentServiceRegister(newService);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

在consul上注册成功后会显示Web-Socket的注册服务名称

二 webSocket 在线测试工具

http://ws.douqq.com/
http://www.jsons.cn/websocket/

三 注意问题

Websocker注入Bean问题
https://blog.csdn.net/moshowgame/article/details/83415545
WebSocket注入@Bean@Autowired
在WebSocket也是这样注入,因 SpringBoot+WebSocket 对每个客户端连接都会创建一个 WebSocketServer(@ServerEndpoint 注解对应的) 对象,Bean 注入操作会被直接略过,因而手动注入一个全局变量
因而一般通过
SpringUtils.getBean
根据上下文获取beanConfigurableListableBeanFactory.getBean(),可以有两种参数类型:

传入String格式的类名
传入类.Class的类
动态调用spring容器中的bean 实现数据库的操作

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/405754
推荐阅读
相关标签
  

闽ICP备14008679号