package com.skyable.deploy.utils;
import com.skyable.deploy.handler.StargoLogWebSocket;
import org.springframework.scheduling.annotation.Async;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/** 实时显示日志 */
public class LogView {
private long lastTimeFileSize = 0; // 上次文件大小
/**
* 实时输出日志信息
*
* @param logFile 日志文件
* @throws IOException
*/
@Async
public void realtimeShowLog(File logFile, Integer clusterId) throws IOException {
// 给文件增加读写权限
final RandomAccessFile randomFile = new RandomAccessFile(logFile, "rw");
// 启动一个线程每5秒钟读取新增的日志信息
ScheduledExecutorService exec = Executors.newScheduledThreadPool(1);
exec.scheduleWithFixedDelay(
new Runnable() {
@Override
public void run() {
try {
// 获得变化部分的
randomFile.seek(lastTimeFileSize);
String tmp = "";
while ((tmp = randomFile.readLine()) != null) {
StargoLogWebSocket.sendMessage(clusterId, new String(tmp.getBytes("ISO8859-1")));
System.out.println(new String(tmp.getBytes("ISO8859-1")));
}
lastTimeFileSize = randomFile.length();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
},
0,
3,
TimeUnit.SECONDS);
}
public static void main(String[] args) throws Exception {
LogView view = new LogView();
final File tmpLogFile = new File("C:\\Users\\Administrator\\Desktop\\cluster-91.yaml");
view.realtimeShowLog(tmpLogFile, 1);
}
}
package com.skyable.deploy.handler;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
@Slf4j
@ServerEndpoint(value = "/stargoLog/{clusterId}")
@Component
public class StargoLogWebSocket {
/**
* 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
*/
private static AtomicInteger ONLINE_COUNT = new AtomicInteger(0);
/**
* concurrent包的线程安全Map,用来存放每个客户端对应的Session对象。
*/
private static Map<Integer,Session> WEBSOCKET_MAP = new ConcurrentHashMap<>();
/**
* 客户端标识
*/
private Integer clusterId;
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session, @PathParam("clusterId") Integer clusterId) {
this.clusterId = clusterId;
WEBSOCKET_MAP.put(clusterId,session);
//统计当前在线的虚拟设备数量
addOnlineCount();
log.info("stargo log websocket connect ok! {}", getOnlineCount());
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
WEBSOCKET_MAP.remove(this.clusterId);
subOnlineCount();
log.info("stargo log websocket disconnect {}", getOnlineCount());
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息
*/
@OnMessage
public void onMessage(String message, Session session) {
log.info("receive message from client {} and message is {}", session.getId(), message);
}
@OnError
public void onError(Session session, Throwable error) {
log.error("client {} has an error {}", session.getId(), error.getMessage());
}
public static void sendMessage(Integer clusterId, Object message) {
//this.session.getBasicRemote().sendText(message);
//this.session.getAsyncRemote().sendText(message);
Session session = WEBSOCKET_MAP.get(clusterId);
if(session != null) {
try {
session.getBasicRemote().sendText(JSON.toJSONString(message));
} catch (IOException e) {
log.error("send message to web error ", e);
}
}
}
private static synchronized int getOnlineCount() {
return ONLINE_COUNT.get();
}
private static synchronized void addOnlineCount() {
ONLINE_COUNT.incrementAndGet();
}
private static synchronized void subOnlineCount() {
ONLINE_COUNT.decrementAndGet();
}
}