客户端和服务端建立长连接可以使用socket建立TCP长连接,也可以建立WebSocket长连接,看起来非常相似,但其实一个是网络传输层上编写套接字实现tcp连接,一个(WebSocket)是应用层的一种封装好的协议。
项目中服务端用到了socket处理tcp直连的方式,客户端很多常见的框架是直接封装到网络层WebSocket用于常见的即时聊天,如果服务端提供的是普通的socket编写的tcp连接,应该详细查看第三方框架是基于什么层面的封装,否则是无法接通长连接的。例如iOS端非常常用的SocketIO基于WebSocket。而基于项目需求,我最后找到了GCDAsyncSocket。
因为常用框架基于的协议自带了保持活跃的功能,或者框架带了保活的功能,所以在iOS端使用socket连接自己用java开启的socket服务时只能收发一次信息。问题就出在客户端必须在连接ip:port的时候同时receive来自服务的信息,并且在接收到信息的时候继续调用接收,保持监听的活跃。
下面是基于springboot开启的java socket简单长连接:
在Application的main函数调用自定义类的startSocketServer方法
@SpringBootApplication
@MapperScan("app.mapper")
public class xxxApplication {
public static void main(String[] args) {
SpringApplication.run(EopswitcherApplication.class, args);
SocketService service = new SocketService();
service.startSocketServer(8888);
}
}
自定义类:
public class SocketService {
//解码buffer
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;
/**
* 启动socket服务,开启监听
*
* @param port
* @throws IOException
*/
public void startSocketServer(int port) {
try {
//打开通信信道
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
//设置为非阻塞
serverSocketChannel.configureBlocking(false);
//获取套接字
ServerSocket serverSocket = serverSocketChannel.socket();
//绑定端口号
serverSocket