springboot專案新增TCP介面資料上傳/下發
阿新 • • 發佈:2020-07-23
一般在啟動類上新增
@SpringBootApplication public class Application extends SpringBootServletInitializer implements CommandLineRunner { @Autowired TcpSocketServer tcpSocketServer; public static void main(String[] args)throws IOException { SpringApplication.run(Application.class, args); } @Override public void run(String... args) throws Exception { tcpSocketServer.startSocketServer(port); //注:此處port繫結埠號 } }
在tcpSocketServer 內: 注意:一般涉及TCP介面的專案都是關於指令上傳和下發的
@Component @Slf4j public class TcpSocketServer extends BaseController { @Autowired TcpServices tcpServices; @Autowired XxxService xxxService; private Charset cs = Charset.forName("UTF-8"); //接受資料緩衝區 private static ByteBuffer sBuffer = ByteBuffer.allocate(1024); //傳送資料緩衝區 private static ByteBuffer rBuffer = ByteBuffer.allocate(1024); //監聽器 private static Selector selector; private static String responseMsg; /** * 啟動socket服務,開啟監聽 * * @param port * @throws IOException */ public void startSocketServer(int port) { try { //開啟通訊通道 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); //設定為非阻塞 serverSocketChannel.configureBlocking(false); //獲取套接字 ServerSocket serverSocket = serverSocketChannel.socket(); //繫結埠號 serverSocket.bind(new InetSocketAddress(port)); //開啟監聽器 selector = Selector.open(); //將通訊通道註冊到監聽器 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); //監聽器會一直監聽,如果客戶端有請求就會進入相應的事件處理 while (true) { selector.select();//select方法會一直阻塞直到有相關事件發生或超時 Set<SelectionKey> selectionKeys = selector.selectedKeys();//監聽到的事件 for (SelectionKey key : selectionKeys) { handle(key); } selectionKeys.clear();//清除處理過的事件 } } catch (Exception e) { e.printStackTrace(); } } /** * 處理不同的事件 * * @param selectionKey * @throws IOException */ private void handle(SelectionKey selectionKey) throws IOException { ServerSocketChannel serverSocketChannel = null; SocketChannel socketChannel = null; String requestMsg = ""; int count = 0; if (selectionKey.isAcceptable()) { //每有客戶端連線,即註冊通訊通道為可讀 serverSocketChannel = (ServerSocketChannel) selectionKey.channel(); socketChannel = serverSocketChannel.accept(); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ); } else if (selectionKey.isReadable()) { socketChannel = (SocketChannel) selectionKey.channel(); rBuffer.clear(); count = socketChannel.read(rBuffer); //讀取資料 if (count > 0) { rBuffer.flip(); //從快取區頭部開始讀取資料操作 requestMsg = String.valueOf(cs.decode(rBuffer).array()); //快取區讀取到的資料 } xxxServices.dealMethods(requestMsg); //這裡是處理從TCP介面上傳的資料業務層,一般可以在業務層根據switch case來對不同資料進行分類方法處理 sBuffer = ByteBuffer.allocate(responseMsg.getBytes("UTF-8").length);
//一般responseMsg為從資料庫或其他資料來源處獲取的資料字串
//此處為指令下發
responseMsg=configurationMap.toString();
sBuffer.put(responseMsg.getBytes("UTF-8")); sBuffer.flip(); socketChannel.write(sBuffer); }
socketChannel.close(); } } } }