使用springboot 和 redis 的list 的队列属性 实现 socket 长连接请求服务器功能
话不多说直接上代码:
package com.veoer.mind.manager; import net.sf.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; import java.io.*; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; import java.util.concurrent.TimeUnit; /** * auth wxt 2020-01-15 * socket 长连接处理 */ @Component @Configuration public class SocketClientLonManager { private Socket mSocket = null; private OutputStream outputStream;//输出流,用于发送心跳 @Value("${socket_client.host}") private String host;//="192.168.254.36"; @Value("${socket_client.port}") private int port;//=9877; @Autowired private RedisManager redisManager; public SocketClientLonManager() { } /** * 这里来个初始化 */ public void init(){ // 创建 socket 并连接服务器 try { mSocket = new Socket(host, port); if(!mSocket.getKeepAlive()) mSocket.setKeepAlive(true);//true,若长时间没有连接则断开 if(!mSocket.getOOBInline())mSocket.setOOBInline(true);//true,允许发送紧急数据,不做处理 outputStream = mSocket.getOutputStream();//获得socket的输出流 } catch (IOException e) { e.printStackTrace(); } } public void run() { // 和服务端进行通信 Thread readerThread = new Thread(this::readResponse); readerThread.start(); //来一个心跳包 Thread heardThread = new Thread(this::startThreadSocket); heardThread.start(); try { if (mSocket.isClosed()){ SocketAddress socketAddress = new InetSocketAddress(host,port); mSocket.connect(socketAddress); } //向服务器端第一次发送字符串 DataOutputStream doc = new DataOutputStream(outputStream); while (true) { String msg = redisManager.rightPop("device_send_msg",100, TimeUnit.HOURS); doc.writeUTF(msg); outputStream.flush(); } }catch (IOException e){ e.printStackTrace(); } } /** * 返回的结果 */ private void readResponse() { try { DataInputStream in = new DataInputStream(mSocket.getInputStream()); //向服务器端第二次发送字符串 while (true) { String res = in.readUTF(); if (!"".equals(res) && null != res ) { JSONObject revertjson = JSONObject.fromObject(res); if("heartbeat".equals(revertjson.getString("type"))){ redisManager.leftPush("device_revert_heartbeat", res); redisManager.setExpire("device_revert_heartbeat",18L, TimeUnit.SECONDS); }else{ redisManager.leftPush("device_revert_msg", res); } } } } catch (IOException e) { e.printStackTrace(); } } /** * 心跳包发送 */ public void startThreadSocket(){ final String socketContent = "{\"type\":\"heartbeat\"}";// + "\n"; while (true) { try { Thread.sleep(20 * 1000);//20s发送一次心跳 redisManager.leftPush("device_send_msg",socketContent); } catch (Exception e) { e.printStackTrace(); } } } }
最基础的socket 类
项目启动时启动socket 发送心跳包
package com.veoer.mind.config; import com.veoer.mind.manager.SocketClientLonManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @Component @Order(value = 2) public class SocketStartInint implements ApplicationRunner { @Autowired SocketClientLonManager socketClientLonManager; @Override public void run(ApplicationArguments args) throws Exception { //启动socket 长连接 线程。 System.out.println("socket Init"); socketClientLonManager.init(); socketClientLonManager.run(); } }
//服务端
package com.wxt.socket.demo.socketclient; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class EchoServer { private final ServerSocket mServerSocket; public EchoServer(int port) throws IOException { // 1. 创建一个 ServerSocket 并监听端口 port mServerSocket = new ServerSocket(port); } public void run() throws IOException { // 2. 开始接受客户连接 Socket client = mServerSocket.accept(); handleClient(client); } private void handleClient(Socket socket) throws IOException { InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream(); byte[] buffer = new byte[1024]; int n; while ((n = in.read(buffer)) > 0) { System.out.write(buffer, 0, n); out.write(buffer, 0, n); } } public static void main(String[] argv) { try { EchoServer server = new EchoServer(9877); server.run(); } catch (IOException e) { e.printStackTrace(); } } }
以上便是所有了,剩下的就是根据实际项目去修改代码了。