思路很简单就是在 web 服务器开启一个死循环的 socket 线程监听客户端的数据,实现一对多的监听。思路很简单但实现起来并不容易,线程阻塞,线程间通信,主函数向线程传值,实现有控制的向 client 客户端发送消息等等很多问题都不好解决,为了解决这些问题也是费尽心思。
SocketThread
public class SocketThread extends Thread {
private ServerSocket serverSocket = null;
public SocketThread(ServerSocket serverScoket) {
try {
if (null == serverSocket) {
this.serverSocket = new ServerSocket(8877);
System.out.println("socket start");
}
} catch (Exception e) {
System.out.println("SocketThread创建socket服务出错");
e.printStackTrace();
}
}
@Override
public void run() {
while (!this.isInterrupted()) {
int count = 0;
while (true) {
try {
Socket socket = serverSocket.accept();
if (null != socket && !socket.isClosed()) {
count++;
System.out.println("当前连接"+count);
// 处理接受的数据
SocketOperate SocketThread = new SocketOperate(socket);
SocketThread.start();
SocketThread.setPriority(4);//设置优先级避免卡死
}
socket.setSoTimeout(3000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public void closeSocketServer() {
try {
if (null != serverSocket && !serverSocket.isClosed()) {
serverSocket.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
SocketServiceLoader
public class SocketServiceLoader implements ServletContextListener {
// socket server 线程
private SocketThread socketThread;
@Override
public void contextDestroyed(ServletContextEvent arg0) {
if (null != socketThread && !socketThread.isInterrupted()) {
socketThread.closeSocketServer();
socketThread.interrupt();
}
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
// TODO Auto-generated method stub
if (null == socketThread) {
// 新建线程类
socketThread = new SocketThread(null);
// 启动线程
socketThread.start();
}
}
}
SocketOperate
public class SocketOperate extends Thread {
@Autowired
private ParkSpaceService SpaceService;
public static String res;
private Socket socket;
public void setFlag(boolean flag){
System.out.println("set is start");
SocketOperate.flag = flag;
}
public void setMessage(String msg){
SocketOperate.ServiceMessage = msg;
}
public String getData(){
return res;
}
public SocketOperate(Socket socket) {
this.socket = socket;
}
@SuppressWarnings("unused")
public void run() {
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
OutputStream os = null;
PrintWriter pw = null;
try {
is = socket.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
byte[] temp = new byte[1024];
int length = 0;
String data = "";
while((length = is.read(temp)) != -1) {
data += new String(temp,0,length);
}
System.out.println("客户端对服务端说 " + data);
res = data;
/**
* 客户端返回车场信息,对数据库进行操作
*/
if(res!=null&&!res.equals("")){
service//对数据库操作
}
socket.shutdownInput();// 关闭socket输入流
// 获取输出流,向客户端输出
os = socket.getOutputStream();
pw = new PrintWriter(os);
pw.write(SocketOperate.ServiceMessage);//向客户端发送内容
pw.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭资源
if (pw != null)
pw.close();
try {
if (os != null)
os.close();
if (is != null)
is.close();
if (isr != null)
isr.close();
if (br != null)
br.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
这三个类就是基于 socket 服务器的核心代码,合理运用并配合 SSM 框架就可以实现简单的物联操作了