Title
Logan港
细节决定成败,知识改变命运。

前言:

  最近工作中有一个需求,就是服务端要主动推送消息给客户端,而我们平常的Http请求只能一请求一响应,为此学习了webScokset通讯技术,以下介绍的是java 通过SpringBoot集成webScoket搭建服务端。


1.引入webScoket依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
            <version>2.1.6.RELEASE</version>
        </dependency>

2.bean注入

  • ServerEndpointExporter 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

}

3.创建scoket的Server服务

  创建一个java类 WebScoketServer,以下为我自己写的一个小demo,实现的就是服务端和客户端一个对话(客户端没有搭建用的网页测试),效果我会在下面测试演示。
  其他具体业务逻辑在连接成功或者收到信息后方法里进行处理

@ServerEndpoint("/webSocket/{username}")
@Component
@Slf4j
public class WebScoketServer {

    //concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
    private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();

    private static Map<Session, List<String>> map =new HashMap<>();

    //发送消息
    public void sendMessage(Session session, String message) throws IOException {
            synchronized (session) {
                System.out.println("发送数据:" + message);
                session.getBasicRemote().sendText(message);
            }

    }


    //建立连接成功调用
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "username") String userName){
        log.info("连接建立 userName是{}",userName);
        sessionPools.put(userName,session);
        List<String> list =new ArrayList<>();
        list.add("服务端--》哈哈哈建立连接后的回复         ");
        map.put(session,list);
        try {
            sendMessage(session,list.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("连接建立");
    }

    //关闭连接时调用
    @OnClose
    public void onClose(@PathParam(value = "username") String userName){
        log.info("连接关闭 userName是{}",userName);
        System.out.println("连接关闭");
    }

    //收到客户端信息后
    @OnMessage
    public void onMessage(String message,@PathParam(value = "username") String userName) throws IOException{
        log.info("收到消息 message是{}",message);
        try {
            Session session = sessionPools.get(userName);
            List<String> list = map.get(session);
            list.add("客户端--》"+message+"                        ");
            list.add("服务端--》我收到消息:"+message+"                        ");
            map.put(session,list);


            sendMessage(session,list.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("收到消息");
    }

    //错误时调用
    @OnError
    public void onError(Session session, Throwable throwable){
        log.info("连接错误");
        System.out.println("连接错误");
    }
	
	
	
	//自己提供sessionPools和map的get  set方法
}

4.测试

直接百度搜webScoket在线调试工具 然后进行访问 以下这就说明搭建成功了
image

5.服务端主动访问客户端

接下来我们写个个接口 尝试下服务器主动发送消息给客户端接下来我们写个个接口 尝试下服务器主动发送消息给客户端

  • 5.1我们建立两个回话连接,分别为zhangsan和lisi

    image

  • 5.2通过访问接口可以看到我们建立的两条链接

    image

  • 5.3方便测试 内容为hahaha 往zhangsan那个链接中发送

    image

  • 5.4 通过访问接口我们可以看到客户端那边收到了服务端主动请求的内容

    image

posted on 2022-01-12 11:17  Logan港  阅读(390)  评论(0编辑  收藏  举报