本文章是对webSocket的学习,在使用webSocket进行客户端-服务端的交互。
参考文章: Java基于Socket的简单推送,在文章在服务端 输入后回车 ,可进行对客户端的信息发送,同时进行回馈。
以下为自行改进:服务端定时推送信息到客户端,可根据自行需要进行调整。
说明:jdk1.8,在定时的选择,是服务端或者客户端断开可以重新连接。
Server:
package demo4;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class MyPushServer {
//存储连接ip
ArrayList<Socket> sockets = new ArrayList<Socket>();
//定时器
private ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
//计数
private static int i=1;
//主程序
public static void main(String[] args) {
MyPushServer myPushServer = new MyPushServer();
try {
myPushServer.start();
} catch (IOException e) {
e.printStackTrace();
}
}
//程序运行
public void start() throws IOException {
@SuppressWarnings("resource")
ServerSocket serverSocket = new ServerSocket(4000);
System.out.println("服务启动成功···");
while (true) {//长启动
Socket socket = serverSocket.accept();
System.out.println("server started... http:/"+ socket.getLocalAddress() + ":" + socket.getPort());
System.out.println(socket.getLocalSocketAddress() + ":"+ socket.getLocalPort());
sockets.add(socket);//添加ip列表
if(i == 1){//保证只需起来一次
synchronized (ServerSocket.class) {
ServerThread serverThread = new ServerThread();
serverThread.start();
}
}
i++;
}
}
//线程任务
class ServerThread extends Thread {
private BufferedReader reader;
private BufferedWriter writer;
private BufferedReader read;
public ServerThread() {
Runnable runnable = new Runnable() {
public void run() {
//发送内容-流
String str = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
InputStream inputStream = new ByteArrayInputStream(str.getBytes());
reader = new BufferedReader(new InputStreamReader(inputStream));
}
};
// 第二个参数为首次执行的延时时间,第三个参数为定时执行的间隔时间
// 第一次执行间隔为10毫秒,随后1000毫秒执行循环
service.scheduleAtFixedRate(runnable, 10, 1000, TimeUnit.MILLISECONDS);
}
@Override
public void run() {
String content = null;//发送内容
String getContent = null;//返回内容
while (true) {
try {
if ((content = reader.readLine()) != null) {
for (Socket socket : sockets) {
System.out.println("socket:"+socket);
try{
socket.sendUrgentData(0xFF); //验证连接是否断开,以忽悠为一个字节的发送进行验证
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
writer.write(content);
writer.newLine();
writer.flush();//发送
read = new BufferedReader(new InputStreamReader(socket.getInputStream()));
if((getContent = read.readLine()) != null) {
System.out.println(getContent);
}
}catch(Exception ex){
sockets.remove(socket);//移除断开的连接
continue;
}
}
}
} catch (Exception e) {
e.getStackTrace();
}
}
}
}
}
Client
package demo4;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Timer;
import java.util.TimerTask;
public class MyPushClient {
private Socket socket;
public static void main(String[] args) {
startConn();
}
/**
* 长连接(可断线重连)
* @Title: startConn
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param:
* @return: void
* @throws
*/
public static void startConn() {
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
MyPushClient myPushClient = new MyPushClient();
try {
myPushClient.start();
timer.cancel();
System.out.println("连接成功!");
} catch (Exception e1) {
System.out.println("连接失败,重新连接中···");
}
}
};
long delay = 0;
long intevalPeriod = 1 * 1500;
timer.scheduleAtFixedRate(task, delay, intevalPeriod);
}
/**
* 开始连接
* @Title: start
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param: @throws IOException
* @return: void
* @throws
*/
public void start() throws IOException {
socket = new Socket("10.200.47.222", 4000);
System.out.println("server connection..");
ClientThread clientThread = new ClientThread();
clientThread.start();
}
/**
* 连接线程-事件
* @ClassName: ClientThread
* @Description:TODO(这里用一句话描述这个类的作用)
* @author: [zhu]
* @date: 2017年6月12日 下午4:59:35
*/
class ClientThread extends Thread {
private BufferedReader reader;
private BufferedWriter writer;
public ClientThread() {
try {
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
String content = null;
while (true) {
try {
if ((content = reader.readLine()) != null) {
System.out.println(content);
writer.write("收到消息");
writer.newLine();
writer.flush();
}
} catch (IOException e) {
// 断线重连
startConn();
break;
}
}
}
}
}
最后:可能会出现乱码,待解决中,会面完善会及时补上。