webflux(reactor3)实现websocket客户端

本文介绍websocket客户端实现的一种方式

闲来无事:也撸了一个demo放在码云上,当然如果看不懂,也可以留言,不想写博客专门讲这个服务端,现在很多博客也讲了服务端怎么做,虽然很多讲得不全,实在需要搞懂这个服务端怎么写的也可以加qq:857113009(服务端实现,简单封装了一下发布订阅):https://gitee.com/hellobb/webflux
(沃特玛傻了,前面放了几个月,居然放在私有库了)

服务端请参考这三个地址:
https://www.cnblogs.com/limuma/p/9315517.html
http://www.codebelief.com/article/2019/05/webflux-analysis-on-websocket-request-processing/
https://cloud.tencent.com/developer/article/1480108

客户端demo使用main方法实现,实际项目中需要根据自己的修改

package com.ontrade.quotation;

import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.concurrent.CountDownLatch;
import org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.publisher.UnicastProcessor;
import reactor.netty.http.client.HttpClient;
import reactor.netty.tcp.TcpClient;
//因为是用main启动的,所以都是静态方法,实际项目需要修改
public class WebsocketTest {

  //只是为了阻塞主线程,防止退出,所以,真正使用的时候需要去除相关的这个东西
  static CountDownLatch countDownLatch = new CountDownLatch(1);
  //自定义的发送器
  static UnicastProcessor<String> directProcessor = UnicastProcessor.create();

  public static void main(String[] args) {
    websocket();
    directProcessor.onNext("发送了一条数据");
    directProcessor.onNext("{\"FID\":\"003\",\"SUB\":\"OFEX.BTCPERP.Depth\"}");
    try {
      countDownLatch.await();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

  public static void websocket() {

    ReactorNettyWebSocketClient client = new ReactorNettyWebSocketClient(httpClient());
    try {
      client.execute(new URI("ws://10.17.145.23:9988"), session -> {
        Mono<Void> input = session.receive().doOnNext(webSocketMessage -> {
          System.out.println("收到消息:" + webSocketMessage.getPayloadAsText(Charset.forName("UTF-8")));
        }).doOnError(throwable -> System.out.println("发生异常:" + throwable))
            .doOnComplete(() -> System.out.println("结束")).then();
        Mono<Void> output = directProcessor.map(message -> session
            .textMessage(message))
            .flatMap(webSocketMessage -> session.send(Mono.just(webSocketMessage))).then();
        //output也可以这样写,与上面二选一
      /*  output=  session.send(Flux.create(
            tFluxSink -> {
              directProcessor.doOnNext(msg -> {
                tFluxSink.next(session.textMessage(msg));
              }).doFinally((x) -> {
                tFluxSink.complete();
              }).subscribe();
            }));*/

        return Mono.zip(input, output).then()
            .doFinally(
                signalType -> {
                  System.out.println("连接结束了,不知道是发生的了异常,还是正常断开,如果要重连,可以在这儿想办法再次发起连接");
                  countDownLatch.countDown();
                });
      }).onTerminateDetach().doOnError(throwable -> System.out.println("发生异常:"+throwable))
          .subscribe(aVoid -> System.out
              .println("这个打印只是想告诉使用的人,reactor中所有的发布订阅最终操作为订阅操作(subcribe)"));
    } catch (URISyntaxException e) {
      e.printStackTrace();
    }
  }

  //实际项目中,这个对象可以用@Bean,然后注入
  public static HttpClient httpClient() {

    TcpClient tcpClient = TcpClient.create()
        .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1000)
        .doOnConnected(connection ->
            connection.addHandlerLast(new ReadTimeoutHandler(100))
                .addHandlerLast(new WriteTimeoutHandler(10)));
    return HttpClient.from(tcpClient);
  }
}


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要在Spring Boot中整合WebFlux实现WebSocket服务器,可以按照以下步骤进行操作: 1. 创建一个Spring Boot项目:使用Spring Initializr或手动创建一个基于Spring Boot的项目。 2. 添加依赖:在项目的pom.xml(Maven)或build.gradle(Gradle)文件中添加以下依赖项: ```xml <!-- Spring Boot WebFlux --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> <!-- Spring Boot WebSocket --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> ``` 3. 创建WebSocket处理器:创建一个WebSocket处理器类,实现`WebSocketHandler`接口。该处理器将处理WebSocket连接的打开、关闭以及消息传递等操作。 ```java import org.springframework.web.reactive.socket.WebSocketHandler; import org.springframework.web.reactive.socket.WebSocketMessage; import org.springframework.web.reactive.socket.WebSocketSession; import reactor.core.publisher.Mono; public class MyWebSocketHandler implements WebSocketHandler { @Override public Mono<Void> handle(WebSocketSession session) { // 处理WebSocket连接的逻辑 return session.send( session.receive() .map(WebSocketMessage::getPayloadAsText) .map(session::textMessage) ); } } ``` 4. 配置WebSocket路由:创建一个配置类,配置WebSocket的路由和处理器。 ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.reactive.config.EnableWebFlux; import org.springframework.web.reactive.config.WebFluxConfigurer; import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping; import org.springframework.web.reactive.socket.server.support.WebSocketHandlerAdapter; import java.util.HashMap; import java.util.Map; @Configuration @EnableWebFlux public class WebSocketConfig implements WebFluxConfigurer { @Bean public WebSocketHandlerAdapter handlerAdapter() { return new WebSocketHandlerAdapter(); } @Bean public SimpleUrlHandlerMapping handlerMapping() { Map<String, WebSocketHandler> map = new HashMap<>(); map.put("/websocket", new MyWebSocketHandler()); SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping(); mapping.setOrder(1); mapping.setUrlMap(map); return mapping; } } ``` 5. 启动应用程序:启动Spring Boot应用程序,WebSocket服务器将在`/websocket`路径下监听连接。 现在,你已经成功地在Spring Boot中整合了WebFlux实现了一个简单的WebSocket服务器。你可以使用前代码(如JavaScript)来连接并测试WebSocket服务器。希望对你有所帮助!如果有任何问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值