java与python通过websocket进行通信

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

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Protobuf是一种数据序列化格式,它可以将结构化数据转换为二进制格式,以便在网络上进行传输或在存储介质上进行持久化。WebSocket是一种在客户端和服务器之间建立持久连接的通信协议。它允许双向通信,使得服务器可以主动向客户端推送数据。 当使用WebSocket进行通信时,你可以使用Protobuf来序列化和反序列化消息。通过将Protobuf消息转换为二进制数据,你可以在WebSocket上发送这些数据。接收方可以解析这些二进制数据,并将其转换回Protobuf消息。 以下是使用Protobuf和WebSocket进行通信的一般步骤: 1. 定义Protobuf消息:首先,你需要定义消息的结构和字段。使用Protobuf语言定义(.proto文件)来定义消息类型和字段。 2. 生成代码:使用Protobuf编译器将.proto文件编译成相应的编程语言代码。例如,你可以使用protoc工具生成JavaPython、C++等语言的代码。 3. 序列化和反序列化:在发送方,你可以使用生成的代码将消息对象序列化为二进制格式。在接收方,你可以使用相同的生成的代码将收到的二进制数据反序列化为消息对象。 4. 建立WebSocket连接:在客户端和服务器之间建立WebSocket连接。这涉及到握手过程,以确保双方可以进行双向通信。 5. 发送和接收消息:一旦WebSocket连接建立,你可以使用WebSocket发送和接收消息。在发送方,将Protobuf消息序列化为二进制数据,并通过WebSocket发送给接收方。在接收方,接收到的数据可以通过Protobuf进行反序列化,以恢复原始的消息对象。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值