springboot+websocket+netty+getway+consul的集成

一 配置集成

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>

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();
    }
}

在端点类上加上@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);
    }

}

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

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);
    }

}

在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 实现数据库的操作

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值