见证Android消息推送时刻--笔记---Socket即时通讯机制

         前几天在"慕课网"看到了郭霖大神的视频----点击打开链接


"见证Android消息推送时刻",由于自己这段时间也在做即时通讯,作为初级码农,顿时感到与大神如此的接近,所以决定追随大神的步伐,把郭神的每一段代码,每一句话都记下来认真学习,笔记分享给大家,一起学习.


1 IM通讯机制研究

       长连接  短连接
        即时通讯属于长连接,维护一个服务,一直监听消息的到达
2 实现在控制台输出内容在服务端接收
        ----客户端代码:这个类实现了控制台输出文本
                  
 /**
 * 消息推送机制客户端代码
 * @author fflin learned by GuoLin
 *
 */

public class SocketClient {
  
    public static void main(String[] args) {

        /**

         * 实现用户在命令行输出消息

         */

        SocketClient socketClient = new SocketClient();

        socketClient.start();

        

    }

    public void start(){

        BufferedReader inBufferedReader;

        try {

            inBufferedReader = new BufferedReader(new InputStreamReader(System.in));

            String inputContent;

            while(!(inputContent = inBufferedReader.readLine()).equals("bye")){

                System.out.println(inputContent);

            }

        } catch (Exception e) { 

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }

         ----服务端代码:接收客户端消息
   
        public class SocketServer {
        public static void main(String[] args) {
            SocketServer mSocketServer = new SocketServer();
            mSocketServer.start();
        }
        public void start(){
            ServerSocket mServerSocket; 
            BufferedReader reader;
            /**
             * 创建ServerSocket对象,参数是端口号,
             * accept方法表示阻塞服务,等待客户端接入
             */
            try {
                mServerSocket = new ServerSocket(9998);
                Socket mSocket = mServerSocket.accept();
                reader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
                /**
                 * 客户端发送过来的消息
                 */
                String receivedMessage;
                while((receivedMessage = reader.readLine()) != null){
                    System.out.println(receivedMessage);
                }
                
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
}

            ----- 客户端创建Socket消息对象,通过创建输出流,发送消息到服务器
         
 //创建服务器的Socket连接,参数:IP地址,端口号
            socket = new Socket("127.0.0.1",9998);
            //发送消息
            writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            inBufferedReader = new BufferedReader(new InputStreamReader(System.in));
            String inputContent;
            while(!(inputContent = inBufferedReader.readLine()).equals("bye")){
                writer.write(inputContent+"\n");
                writer.flush();
                System.out.println(inputContent);
            }  

  
         ---- 服务端接收到消息,打印到控制台
 
 mServerSocket = new ServerSocket(9998);
                System.out.println("服务启动了....");
                Socket mSocket = mServerSocket.accept();
                System.out.println("客户端:"+mSocket.hashCode()+"已经连接服务器");


         -----服务端接收到消息,打印
                   
       -----目前实现了从客户端发送消息给服务端,如果要实现服务端发送消息到客户端,只需要把服务端和客户端的reader和writer 替换
                 ---服务端创建writer对象,回复客户端消息
                   writer = new BufferedWriter(new OutputStreamWriter(mSocket.getOutputStream()));
                 ---客户端创建reader,接收服务端消息
               reader =  new  BufferedReader( new  InputStreamReader(socket.getInputStream()));
3 问题:
         目前虽然实现了客户端与服务端的长连接,可是客户端不能被动接受服务端的消息,只能主动发送消息到服务器,才会收到服务器返回的消息            
4 完善优化Socket消息机制
         ---客户端开启服务器消息监听器,目前客户端已经拥有了随时接受服务端返回消息的能力
               public void startServerReplyListener(final BufferedReader reader){
        //请求网络等耗时操作要放在子线程中运行
        new Thread(new Runnable() {
            
            @Override
            public void run() {
                try {
                    String response;    
                    //相当于子线程阻塞,一直监听服务器的消息到达
                    while((response = reader.readLine()) != null){
                        System.out.println(response);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                
            }
        }).start();

    }

         -----定时任务
              
    
         -----注意一个问题,在读取数据的操作中,程序判断以"\n"(换行符)为一段文本的结束
         
5 服务端目前存在的问题:只允许一个客户端接入
               public void manageConnection(Socket socket){
        //为每个建立连接的Socket建立一个线程,进行管理
        new Thread(new Runnable() {
            
            @Override
            public void run() {
                try {
                    reader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
                    writer = new BufferedWriter(new OutputStreamWriter(mSocket.getOutputStream()));    
                    /**
                     * 客户端发送过来的消息
                     */
                    String receivedMessage;
                    while((receivedMessage = reader.readLine()) != null){
                        System.out.println(receivedMessage);
                        //服务器收到消息,回复给客户端,注意加换行符
                        writer.write("服务端收到消息,回复:"+receivedMessage+"\n");
                        writer.flush();
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }finally{
                    try {
                        reader.close();
                        writer.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                
            }
        }).start();
              -----调用管理客户端接入的方法
                         while (true) {
                   mSocket = mServerSocket.accept();
                           manageConnection(mSocket);
                System.out.println("客户端:" + mSocket.hashCode() + "已经连接服务器");
            }
        ----运行效果
              





         




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值