java 实现心跳

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.net.InetSocketAddress;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.Date;

import java.util.HashMap;

import java.util.Map;

import org.dom4j.Document;

import org.dom4j.DocumentException;

import org.dom4j.DocumentHelper;

import cn.edu.zju.cst.mina.im.server.entity.User;

import cn.edu.zju.cst.mina.im.server.handler.ServerControler;

public class UserStateManage extends Thread {
//在线用户状态列表

static HashMap userStateList = new HashMap();

Object hashLock = new Object();

//当前的连接数和工作线程数

static int workThreadNum = 0;

static int socketConnect = 0;

private ServerSocket serverSocket;

//服务器IP

private String host = "10.82.81.79";

//服务器端口

private int stateReportPort = 60001;

//设置心跳包的结束标记

String endFlag = "";

CharSequence csEndFlag = endFlag.subSequence(0, 10);

//扫描间隔

private int scanTime = 1800;

@Override

public void run() {
//绑定端口,并开始侦听用户的心跳包

serverSocket = startListenUserReport(stateReportPort);

if(serverSocket == null){
System.out.println("【创建ServerSocket失败!】");

return;

}

//启动扫描线程

Thread scanThread = new Thread(new scan());

scanThread.start();

//等待用户心跳包请求

while(true){
Socket socket = null;

try {
socketConnect = socketConnect + 1;

//接收客户端的连接

socket = serverSocket.accept();

//为该连接创建一个工作线程

Thread workThread = new Thread(new Handler(socket));

//启动工作线程

workThread.start();

} catch (IOException e) {
e.printStackTrace();

}

}

}

/**

* 创建一个ServerSocket来侦听用户心跳包请求

* @param port 指定的服务器端的端口

* @return 返回ServerSocket

* @author dream

*/

public ServerSocket startListenUserReport(int port){
try {
ServerSocket serverSocket = new ServerSocket();

if(!serverSocket.getReuseAddress()){
serverSocket.setReuseAddress(true);

}

serverSocket.bind(new InetSocketAddress(host,port));

System.out.println("【开始在"+serverSocket.getLocalSocketAddress()+"上侦听用户的心跳包请求!】");

return serverSocket;

} catch (IOException e) {
System.out.println("【端口"+port+"已经被占用!】");

if (serverSocket != null) {
if (!serverSocket.isClosed()) {
try {
serverSocket.close();

} catch (IOException e1) {
e1.printStackTrace();

}

}

}

}

return serverSocket;

}

//工作线程类

class Handler implements Runnable{
private Socket socket;

UserState us = null;

User newUser = null;

private int userId;

private int userState;

/**

* 构造函数,从调用者那里取得socket

* @param socket 指定的socket

* @author dream

*/

public Handler(Socket socket){
this.socket = socket;

}

/**

* 从指定的socket中得到输入流

* @param socket 指定的socket

* @return 返回BufferedReader

* @author dream

*/

private BufferedReader getReader(Socket socket){
InputStream is = null;

BufferedReader br = null;

try {
is = socket.getInputStream();

br = new BufferedReader(new InputStreamReader(is));

} catch (IOException e) {
e.printStackTrace();

}

return br;

}

public void run() {
try{
workThreadNum = workThreadNum +1;

System.out.println("【第"+workThreadNum+"个的连接:"+socket.getInetAddress()+":"+socket.getPort()+"】");

BufferedReader br = getReader(socket);

String meg = null;

StringBuffer report = new StringBuffer();

while ((meg = br.readLine()) != null) {
report.append(meg);

if (meg.contains(csEndFlag)) {
us = getReporterUserState(meg, socket);

synchronized (hashLock) {
userStateList.put(userId, us);

}

}

}

}catch(IOException e){
System.out.println("【客户:"+newUser.getUser_id()+"已经断开连接!】");

userStateList.remove( userId );

announceStateChange( userId , -1);

}finally{
if(socket != null){
try {
//断开连接

socket.close();

} catch (IOException e) {
e.printStackTrace();

}

}

}

}

private UserState getReporterUserState(String meg , Socket socket){
UserState us = new UserState();

try {
Document requestDoc = DocumentHelper.parseText(meg);

newUser = ServerControler.parseXmlToUserState(requestDoc,socket);

userId = newUser.getUser_id();

userState = newUser.getUser_state();

us.setFlag(2);

us.setUser_state( userState );

us.setUser_id( userId );

us.setUser_ip(newUser.getUser_ip());

us.setUser_port(newUser.getUser_port());

} catch (DocumentException e) {
System.out.println("【来自客户端的信息不是一个合法的心跳包协议】");

}

return us;

}

}

//扫描线程

class scan implements Runnable{
public void run() {
while (true) {
System.out.println("*******"+new Date()+":扫描线程开始扫描"+"*******");

synchronized (hashLock) {
if(!userStateList.isEmpty()){
//遍历在线用户列表

for (Map.Entry entry : userStateList.entrySet()) {
int flag = entry.getValue().getFlag();

if ( (flag - 1) < 0) {
//在这里通知该用户的好友其状态发生改变

//announceStateChange(entry.getKey() , 0);

}else{
entry.getValue().setFlag(flag - 1);

userStateList.put(entry.getKey(), entry.getValue());

}

System.out.println(entry.getKey() + "-->" + entry.getValue().toString());

}

}else{
System.out.println("现在还没有在线用户!");

}

}

//实现定时扫描

try {
sleep(scanTime);

} catch (InterruptedException e) {
e.printStackTrace();

}

}

}

}

private void announceStateChange(int userId , int state){
System.out.println("通知其好友!");

}

/**

* 查询一个用户是否在线

* @param userId 指定要查询状态的用户的ID

* @return true 在线; false 不在线;

* @author dream

*/

public boolean isAlive(int userId){
synchronized (hashLock) {
return userStateList.containsKey(userId);

}

}

/**

* 返回指定用户ID的状态

* @param userId 指定要查询状态的用户的ID

* @return >0 该用户在线; -1 该用户离线

* @author dream

*/

public int getUserState(int userId){
synchronized (hashLock) {
if(userStateList.containsKey(userId)){
return userStateList.get(userId).getUser_state();

}else{
return -1;

}

}

}

public Object getHashLock() {
return hashLock;

}

public void setHashLock(Object hashLock) {
this.hashLock = hashLock;

}

public String getHost() {
return host;

}

public void setHost(String host) {
this.host = host;

}

public int getStateReportPort() {
return stateReportPort;

}

public void setStateReportPort(int stateReportPort) {
this.stateReportPort = stateReportPort;

}

public String getEndFlag() {
return endFlag;

}

public void setEndFlag(String endFlag) {
this.endFlag = endFlag;

}

public int getScanTime() {
return scanTime;

}

public void setScanTime(int scanTime) {
this.scanTime = scanTime;

}

public static HashMap getUserStateList() {
return userStateList;

}

public static int getWorkThreadNum() {
return workThreadNum;

}

public static int getSocketConnect() {
return socketConnect;

}

//测试本函数的main函数

public static void main(String arg[]){
UserStateManage usm = new UserStateManage();

usm.start();

}

}

 

posted on 2022-04-20 10:52  petroe  阅读(981)  评论(0编辑  收藏  举报

导航