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