web sotkcet server端启动的时候不停地向客户端发送数据
public class MySessionContainer { private final static Map<String, WsSessionUser> WS_SESSION_USER_MAP = new ConcurrentHashMap<>(); public static void addClient(String id, WsSessionUser user) {
WS_SESSION_USER_MAP.put(id, user);
} public static WsSessionUser getClient(String id) {
return WS_SESSION_USER_MAP.get(id);
} public static WsSessionUser removeClient(String id) {
return WS_SESSION_USER_MAP.remove(id);
} public static void sendAll() {
try {
while (true) {
Thread.sleep(10L);
WS_SESSION_USER_MAP.forEach((key, value) -> {
WsSessionUser wsSessionUser = getClient(key);
if (wsSessionUser != null) {
wsSessionUser.sendMessageByPool("hello world!");
}
});
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}}每个连接使用线程池发送数据
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;import java.io.IOException;
import java.util.concurrent.*;/**
* @author saiya
* @date 2018/8/3 0003
*/
@Slf4j
public class WsSessionUser { private WebSocketSession session; private ThreadFactory factory = new ThreadFactoryBuilder().setNameFormat("WsSessionUser-send-thread-pool-%d").build();
private ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<>(2), factory); public WsSessionUser(WebSocketSession session) {
this.session = session;
} public void sendMessageByPool(String message) {
try {
if (!threadPoolExecutor.isShutdown()) {
threadPoolExecutor.execute(() -> sendMessage(message));
}
} catch (RejectedExecutionException e) {
log.error("RejectedExecutionException", e);
threadPoolExecutor.shutdownNow();
try {
log.info("session.close()");
session.close();
} catch (IOException e1) {
log.error("close socket error", e);
}
}
} private void sendMessage(String message) {
try {
session.sendMessage(new TextMessage(message));
} catch (IOException e) {
log.error("send message error,sessionId={}", session.getId(), e);
}
} public ThreadPoolExecutor getThreadPoolExecutor() {
return threadPoolExecutor;
}
}[b]如果发送数据到web socket 客户端超时了,server端的WsSession就会泄露,gc不掉[/b]
比如我在客户端的onMessage方法上使用线程等待1分钟或打个断点1分钟。这个时候服务端就会出现超时错误。问题重现。
新注册,只有200分
public class MySessionContainer { private final static Map<String, WsSessionUser> WS_SESSION_USER_MAP = new ConcurrentHashMap<>(); public static void addClient(String id, WsSessionUser user) {
WS_SESSION_USER_MAP.put(id, user);
} public static WsSessionUser getClient(String id) {
return WS_SESSION_USER_MAP.get(id);
} public static WsSessionUser removeClient(String id) {
return WS_SESSION_USER_MAP.remove(id);
} public static void sendAll() {
try {
while (true) {
Thread.sleep(10L);
WS_SESSION_USER_MAP.forEach((key, value) -> {
WsSessionUser wsSessionUser = getClient(key);
if (wsSessionUser != null) {
wsSessionUser.sendMessageByPool("hello world!");
}
});
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}}每个连接使用线程池发送数据
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;import java.io.IOException;
import java.util.concurrent.*;/**
* @author saiya
* @date 2018/8/3 0003
*/
@Slf4j
public class WsSessionUser { private WebSocketSession session; private ThreadFactory factory = new ThreadFactoryBuilder().setNameFormat("WsSessionUser-send-thread-pool-%d").build();
private ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<>(2), factory); public WsSessionUser(WebSocketSession session) {
this.session = session;
} public void sendMessageByPool(String message) {
try {
if (!threadPoolExecutor.isShutdown()) {
threadPoolExecutor.execute(() -> sendMessage(message));
}
} catch (RejectedExecutionException e) {
log.error("RejectedExecutionException", e);
threadPoolExecutor.shutdownNow();
try {
log.info("session.close()");
session.close();
} catch (IOException e1) {
log.error("close socket error", e);
}
}
} private void sendMessage(String message) {
try {
session.sendMessage(new TextMessage(message));
} catch (IOException e) {
log.error("send message error,sessionId={}", session.getId(), e);
}
} public ThreadPoolExecutor getThreadPoolExecutor() {
return threadPoolExecutor;
}
}[b]如果发送数据到web socket 客户端超时了,server端的WsSession就会泄露,gc不掉[/b]
比如我在客户端的onMessage方法上使用线程等待1分钟或打个断点1分钟。这个时候服务端就会出现超时错误。问题重现。
新注册,只有200分
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货