チャットルームサービスの実装

22216 ワード

このサービス・エンドは、クライアントが接続して新しいスレッドを作成し、パフォーマンスを最適化する必要があります.
ソケットサービス
public class MyServer {
    
    
    private int port;
    private ServerHandler serverHandler; 
    
    public MyServer(int port,ServerHandler serverHandler) throws IOException{
        System.out.println("     .....");
        this.setPort(port);
        this.setServerHandler(serverHandler);
        ServerSocket ss = new ServerSocket(port);
        System.out.println("      .....");
        System.out.println("    "+port+"  .....");
        while (true) {
            Socket s = ss.accept();
            serverHandler.connectService(s);
            Thread receiveListenerThread =  new Thread(new ReceiveDataListener(serverHandler, s));
            receiveListenerThread.setName(s.getInetAddress().getHostAddress());
            receiveListenerThread.start();
        }
    }
    
    
    public int getPort() {
        return port;
    }
    public void setPort(int port) {
        this.port = port;
    }
    public ServerHandler getServerHandler() {
        return serverHandler;
    }
    public void setServerHandler(ServerHandler serverHandler) {
        this.serverHandler = serverHandler;
    }
    
}

オンライン通知
/**
 *     
 * @author huang
 *
 */
public class OnlineNotify implements Runnable{
    
    private String onlineUserName;
    
    public OnlineNotify(String onlineUserName){
        this.onlineUserName = onlineUserName;
    }
    @Override
    public void run() {
        try {            
            Set> set = SocketMap.map.entrySet();
            for (Entry entry : set) {
                Socket s = (Socket) entry.getValue();
                BufferedOutputStream out =new BufferedOutputStream(s.getOutputStream());
                String notifyInfo = "1000|   "+onlineUserName+"      ";
                Tools.sendData(out, notifyInfo);
            }
        } catch (Exception e) {
            
        }
    }

}

受信情報リスニングスレッド
/**
 *        
 * @author huang
 *
 */
public class ReceiveDataListener implements Runnable{
    
    private ServerHandler serverHandler;
    
    private Socket s;
    
    public ReceiveDataListener(ServerHandler serverHandler, Socket s) {
        this.serverHandler = serverHandler;
        this.s = s;
    }

    public void run() {
        while (true) {
            serverHandler.receiveData(s);
        }
    }
    
    
    
}

サービス側処理クラスインタフェース
/**
 *       
 * @author huang
 *
 */
public interface ServerHandler {
    
    /**
     *        
     * @param s
     */
    public void connectService(Socket s)  throws IOException ;
    
    /**
     *         
     * @param s
     * @throws IOException
     */
    public void receiveData(Socket s);
    
    /**
     *        
     * @param s
     * @throws IOException
     */
    public void closeConnect(Socket s);
    
    
}

サービス側処理インタフェース実装クラス
public class ServerHandlerImpl implements ServerHandler {
    
    private ServerBiz sb = new ServerBiz();
    
    public void connectService(Socket s) throws IOException {
        
        System.out.println(s.getInetAddress().getHostAddress()+"      ...");
    }

    public void receiveData(Socket s) {
        
        try {
            BufferedInputStream in = new BufferedInputStream(s.getInputStream());
            String data = Tools.receiveData(in);
            System.out.println("      :"+data);
            String[] datas = data.split("\\|");
            switch (Integer.parseInt(datas[0])) {
                case 1000 :
                    System.out.println("          .....");
                    SocketMap.map.put(datas[1], s);
                    sb.login(s,datas[1]);
                    break;
                case 1001:
                    sb.pocketTransmission(datas[1],datas[2]);
                    break;
                case 1002:
                    sb.transpondMessage(datas[1],datas[2],datas[3]);
                    break;
                case 1010:
                    SocketMap.map.remove(datas[1]);
                    sb.userOffLine(datas[1]);
                    s.close();
                default:
                    break;
            }
            
        } catch (Exception e) {
            // TODO: handle exception
        }

    }
    
    public void closeConnect(Socket s) {
        System.out.println(s.getInetAddress().getHostAddress()+"           ");
    }

    /**
     *         
     * @param data
     * @return
     */
    protected static boolean checkData(String data){
        if(data.indexOf("|") < 0){
            return false;
        }
        String[] datas = data.split("|");
        if(!datas[0].equals("1000") && !datas[0].equals("1001") && !datas[0].equals("1002")){
            return false;
        }
        return true;
    }
}

サービス側業務処理類
public class ServerBiz {
    
    public void login(Socket s,String userName)  throws Exception{
        System.out.println("        ....");
        BufferedOutputStream out =new BufferedOutputStream(s.getOutputStream());
        
        Set> set = SocketMap.map.entrySet();
        String responseMsg = "0000";
        for (Entry en : set) {
            responseMsg = responseMsg +"|"+en.getKey();
        }
        System.out.println(responseMsg);
        Tools.sendData(out, responseMsg);
        
        //
        new Thread(new OnlineNotify(userName)).start();
    }
    
    public void dataTranspond(Socket s) throws Exception{
        
        
    }
    /**
     *   
     * @param s
     * @throws Exception 
     */
    public void pocketTransmission(String user,String msg) throws Exception{
        
        Set> set = SocketMap.map.entrySet();
        for (Entry entry : set) {
            Socket s = (Socket) entry.getValue();
            BufferedOutputStream out =new BufferedOutputStream(s.getOutputStream());
            Tools.sendData(out, "1001|【"+user+"】    :"+msg);
        }
    }
    
    /**
     *       
     * @param user
     * @throws Exception 
     */
    public void userOffLine(String user) throws Exception {
        Set> set = SocketMap.map.entrySet();
        for (Entry entry : set) {
            Socket s = (Socket) entry.getValue();
            BufferedOutputStream out =new BufferedOutputStream(s.getOutputStream());
            Tools.sendData(out, "1010|"+user);
            s.close();
        }
        
    }
    
    /**
     *     
     * @param fromUser    
     * @param toUser    
     * @param msg   
     * @throws Exception 
     */
    public void transpondMessage(String fromUser, String toUser, String msg) throws Exception {
        
        Socket s = SocketMap.map.get(toUser);//      socket
        BufferedOutputStream out =new BufferedOutputStream(s.getOutputStream());
        String message = "1002|【"+fromUser+"】   :"+msg;
        Tools.sendData(out, message);
        
    }

    
}

socket容器
public class SocketMap {
    
    public static Map map = new HashMap();
    
}

ツールクラス
public class Tools {
    
    protected static byte[] getMsgLength(int length){
        System.out.println("    ");
        byte[] bt = new byte[4];
        bt[0] = (byte) (length/1000);
        bt[1] = (byte) (length%1000/100);
        bt[2] = (byte) (length%100/10);
        bt[3] = (byte) (length%10);
        
        return bt;
    }
    
    public static void sendData(BufferedOutputStream out,String message) throws Exception{
        System.out.println("message:"+message);
        byte[] head = Tools.getMsgLength(message.getBytes("UTF-8").length);
        out.write(head);
        out.flush();
        out.write(message.getBytes("UTF-8"));
        out.flush();
    }
    
    public static String  receiveData(BufferedInputStream in) throws Exception{
        int length = readMsgHead(in);
        System.out.println("        :"+length);
        byte[] bt = new byte[length];
        in.read(bt);
        String data = new String(bt,"UTF-8");
        return data;
    }
    
    
    
    protected  static int readMsgHead(BufferedInputStream in) throws IOException{
        int length = 0;
        byte[] bt = new byte[4];
        in.read(bt, 0, 4);
        length = bt[0]*1000+bt[1]*100+bt[2]*10+bt[3];
        return length;
    }
    
    
}

 
転載先:https://www.cnblogs.com/hwyblog/p/7875650.html