java服务端与python客户端通过websocket协议进行通信

遇到一个业务:需要java作为服务端,python作为客户端,进行双向数据传输;
java端发送数据给python,python处理数据后再返回给java端。
研究了挺久的

发现了一个更加精简好用的java框架okhttps,也支持websocket连接,大伙可以去试试
https://github.com/troyzhxu/okhttps
——2023.11.19更新

python客户端

先下载websockets :pip install websockets

import asyncio
import websockets

async def connect_to_websocket():
    async with websockets.connect('ws://localhost:8808/transmission') as websocket:
        # 连接到WebSocket服务端     👆必须是ws或者wss  
        print('已连接到WebSocket服务端')

        while True:
            message = input('请输入要发送的消息:')
            await websocket.send(message)  # 发送消息到服务端
            print('已发送消息 -> ', message)

            response = await websocket.recv()  # 接收服务端的消息
            print('收到消息 -> ', response)

asyncio.get_event_loop().run_until_complete(connect_to_websocket())

java服务端

引入坐标

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

编写配置类,扫描添加有@ServerEndpoint注解的 Bean

/**
* @author Judy
*/
@Configuration
public class WebSocketConfig {

    @Bean
    //注入ServerEndpointExporter,自动注册使用@ServerEndpoint注解的类
    public ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }

}
/**
* @author Judy
*/

@ServerEndpoint(value = "/transmission")//👈

@Slf4j
@Component
public class TransmissionServer  {

    //所有的endpoint实例都用同一个map集合【适用于多个客户端】
    public static final Map<String,Session> onlineUser = new ConcurrentHashMap<>();

    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;

    
   /**
    * 实现服务器主动推送
    */
    public void sendMessage(String message) throws IOException {
        Session python = onlineUser.get("python");
        python.getBasicRemote().sendText(message);
	}

    /**
     * 建立websocket连接后,被调用
     * @param session
     */
    @OnOpen
    public void onOpen(Session session,EndpointConfig config) throws IOException, EncodeException {
        //将session进行保存
        this.session = session;
        onlineUser.put("python",session);
        log.error("有新连接");

        session.getBasicRemote().sendText("连接成功");

    }

    @OnMessage
    public void onMessage(String message, Session session) throws IOException {
        // todo 接收数据 处理数据并且保存到数据库中 需要修改handle属性
        log.error("收到消息");
        session.getBasicRemote().sendText("服务端已收到信息");
        System.out.println(message);

    }
    
    @OnError
    public void onError(Session session, Throwable error){
        error.printStackTrace();
    }
    @OnClose
    public void onClose(){
        log.error("连接关闭");
    }
  
}

启动类加上注解

/**
* @author Judy
*/
@SpringBootApplication
@MapperScan("XXX")

@EnableWebSocket//👈加上这个

public class XXXApplication {

    public static void main(String[] args) {
        SpringApplication.run(XXXApplication.class, args);
    }

}

image.png

2023-06-24 20:21:12.088 ERROR 27616 --- [0.0-8808-exec-1] c.h.r.server.TransmissionServer: 有新连接
2023-06-24 20:21:19.437 ERROR 27616 --- [0.0-8808-exec-9] c.h.r.server.TransmissionServer: 收到消息
1.hi
2023-06-24 20:21:27.580 ERROR 27616 --- [0.0-8808-exec-3] c.h.r.server.TransmissionServer: 收到消息
2.hello
2023-06-24 20:21:58.551 ERROR 27616 --- [0.0-8808-exec-2] c.h.r.server.TransmissionServer: 连接关闭

测试服务器主动推送

/**
* @author Judy
* @create 2023-06-20-21:34
*/
@RestController
@ResponseBody
@RequestMapping("/doDeepin")
public class TransmissionController {
    
    @Autowired
    private TransmissionServer transmissionServer;

    @PostMapping("/text")
    public void doDeepin() throws IOException {
        transmissionServer.sendMessage("hello");
    }
}
import asyncio
import websockets

async def connect_to_websocket():
    async with websockets.connect('ws://localhost:8808/transmission') as websocket:
        # 连接到WebSocket服务端
        print('已连接到WebSocket服务端')

        while True:
            response = await websocket.recv()  # 接收服务端的消息
            print('收到消息 -> ', response)

asyncio.get_event_loop().run_until_complete(connect_to_websocket())

image.png


END

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐