Android用Websocket实现聊天室

最近的项目中要实现一个聊天的功能,类似于斗鱼TV的聊天室功能,与服务器端人商量后决定用WebSocket来做,但是在这之前我只知道Socket但是听都没有听过WebSocket,但是查看了相关的材料以后发现实现一个聊天室其实是很简单的!下面我们先来看看WebSocket。
Autobahn|Android 是由Autobahn开发一个开源的Java/Android网络库,实现了WebSocket协议和Web应用程序消息传输协议来创建本地移动的WebSocket/ WAMP的客服端。
WebSocket允许在网络上双向的发送实时消息,WAMP 为客服端增加了一个协议异步远程调用、推送、订阅。
WebSocket有以下几个特点
1.支持 WebSocket RFC6455, Draft Hybi-10+ and WAMP v1
2.支持Android 2.2以上
3.非常好的兼容性
4.高性能的异步设计
5.非常容易使用的api
6.与Android app非常好的结合
7.没有网络操作在UI线程
8.开源
下面是官网给的一段示例代码

rivate final WebSocketConnection mConnection = new WebSocketConnection();

private void start() {

   final String wsuri = "ws://localhost:9000";

   try {
      mConnection.connect(wsuri, new WebSocketHandler() {

         @Override
         public void onOpen() {
            Log.d(TAG, "Status: Connected to " + wsuri);
            mConnection.sendTextMessage("Hello, world!");
         }

         @Override
         public void onTextMessage(String payload) {
            Log.d(TAG, "Got echo: " + payload);
         }

         @Override
         public void onClose(int code, String reason) {
            Log.d(TAG, "Connection lost.");
         }
      });
   } catch (WebSocketException e) {

      Log.d(TAG, e.toString());
   }
}

是不是挺简单的,在onOpen()方法中做与服务器连接的操作,onTextMessage()是收到服务器发送给客服端的消息,onClose()是与服务器断开走的方法,发送消息用sendTextMessage()。
我是在MsgService 实现与服务器的连接与发送消息的,直接上代码:

public class MsgService extends Service {
    private final IBinder binder = new MsgBinder();
    private boolean flag = false;
    private WebSocketConnection mConnection;
    private Intent intent = new Intent("com.example.communication.RECEIVER");

    public void startSocket(String sn) {

        final String wsuri = "ws://localhost:9000";
        final JSONObject json = new JSONObject();
        try {
            json.put("type", "command");
            json.put("command", "auth");
            json.put("key", Constants.API_KEY);
            json.put("access_token", UserManager.getInstance().getUser()
                    .getUserAccessToken());
            json.put("user_token", UserManager.getInstance().getUser()
                    .getLYUserToken());
            json.put("sn", sn);
        } catch (Exception e) {
              e.printStackTrace();
        }

        try {
            mConnection.connect(wsuri, new WebSocketHandler() {

                @Override
                public void onOpen() {
                    if (!flag) {
                        //与服务器连接认证
                        mConnection.sendTextMessage(json.toString());
                    } else {
                    }
                }

                @Override
                public void onTextMessage(String payload) {
                    intent.putExtra("message", payload);
                    sendBroadcast(intent);//发送广播给Fragment
                }
                @Override
                public void onClose(int code, String reason) {
                    //连接失败也把效应的提示信息告诉用户
                    Map<String, String> map = new HashMap<>();
                    map.put("status", "failed");
                    map.put("type", "command");
                    map.put("command", "auth");
                    String msg = map.toString();
                    intent.putExtra("message", msg);
                    sendBroadcast(intent);

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

    //发送消息的方法
    public void sendMessage(String message) {
        mConnection.sendTextMessage(message);
    }


    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    @Override
    public void onCreate() {
        mConnection = new WebSocketConnection();
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    public class MsgBinder extends Binder {
        /**
         * 获取当前Service的实例
         *
         * @return
         */
        public MsgService getService() {
           return MsgService.this;
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mConnection.disconnect();
    }

}

下面是Fragment的代码

public class ChatRoomFragment extends Fragment {
    private View view, rootView, headView;
    private MsgService msgService;
    private UListView chatlist;//因为ScrollVie与ListView有冲突,重写了ListView
    private static List<ChatMessage> mlist;
    private ChatMessage chatMessage;
    private ChatMessageAdapter chatMessageAdapter;
    private ScrollView scrollView;
    private Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    msgService
                            .startSocket(((PlayActivity) getActivity()).getSn());
                    break;
                default:
                    break;
            }

        }
    };
    //通过聊天室来更新在线人数
    public interface UpdataOnlineUsersListener {
        public void updataOnlineUser(int number);
    }

    private UpdataOnlineUsersListener mCallback;
    private EditText messageEditText;
    private Button sendBtn;
    private Intent mIntent;
    private MsgReceiver msgReceiver;
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d("time", "msg");
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // 返回一个MsgService对象
            MsgService.MsgBinder binder = (MsgService.MsgBinder) service;
            if (binder != null) {
                Log.d("time", "msg");
            }
            msgService = binder.getService();
            if (msgService != null) {
                Log.d("time", "msg");
                Message msg = new Message();
                msg.what = 1;
                handler.sendMessage(msg);
            }
        }
    };

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fragment_chat_room, container, false);
        return view;
    }

    public void bindChatService() {
        getActivity().bindService(mIntent, conn, Context.BIND_AUTO_CREATE);
    }

    public void destoryChatService() {
        getActivity().unbindService(conn);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mCallback = (UpdataOnlineUsersListener) (activity);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        // 动态注册广播接收器
        msgReceiver = new MsgReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("com.example.communication.RECEIVER");
        getActivity().registerReceiver(msgReceiver, intentFilter);
        mIntent = new Intent(getActivity(), MsgService.class);
        bindChatService();
        chatlist = (UListView) view.findViewById(R.id.chatlist);
        messageEditText = (EditText) view.findViewById(R.id.input);
        scrollView = (ScrollView) view.findViewById(R.id.scroll);
        scrollView.setFocusable(false);
        mlist = new ArrayList<ChatMessage>();
        chatMessageAdapter = new ChatMessageAdapter(mlist, getActivity());
        chatlist.setAdapter(chatMessageAdapter);
        chatlist.setVerticalScrollBarEnabled(true);
        sendBtn = (Button) view.findViewById(R.id.send);
        builder = new AlertDialog.Builder(getActivity());
        sendBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                final View view = v;
                if (UserManager.getInstance().getUser().getGuest()) {
                    ToastUtil.getInstance().showToast(getActivity(), getResources().getString(R.string.is_not_login));
                } else {
                    String message = messageEditText.getText().toString();
                    if (!message.equals("")) {
                        JSONObject json = new JSONObject();
                        try {
                            json.put("type", "message");
                            json.put("to", "");
                            json.put("message", message);
                        } catch (Exception e) {
                        }

                        msgService.sendMessage(json.toString());
                    } else {
                        Toast.makeText(getActivity(),
                                getResources().getString(R.string.textisnull),
                                Toast.LENGTH_SHORT).show();
                    }

                }
                HideKeyboard(v);
                messageEditText.setText("");
            }

        });
        rootView = (View) view.findViewById(R.id.rootview);
        rootView.setFocusable(true);
        rootView.setFocusableInTouchMode(true);
        rootView.requestFocus();
        setRetainInstance(true);

    }
    //隐藏软键盘
    private void HideKeyboard(View v) {
        InputMethodManager imm = (InputMethodManager) v.getContext()
                .getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm.isActive()) {
            imm.hideSoftInputFromWindow(v.getApplicationWindowToken(), 0);
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        scrollView.smoothScrollTo(0, 0);
    }
    //接受服务端发送的消息
    public class MsgReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String msg = intent.getStringExtra("message");
            try {
                JSONObject json = new JSONObject(msg);
                if (json.getString("type").equals("command")) {
                    String command = json.getString("command");
                    if (command.equals("auth")) {
                        {
                            chatMessage = new ChatMessage("tips", "服务器连接中...",
                                    "111", "111");
                            mlist.add(chatMessage);
                            chatMessageAdapter.notifyDataSetChanged();
                        }
                        if (json.getString("status").equals("success")) {
                            chatMessage = new ChatMessage("tips", "服务器连接中成功",
                                    "111", "111");
                        } else {
                            chatMessage = new ChatMessage("tips", "服务器连接中失败",
                                    "111", "111");
                        }
                        mlist.add(chatMessage);
                        chatMessageAdapter.notifyDataSetChanged();
                    } else if (command.equals("online_status")) {
                        int onlineUser = json.getInt("online");
                        mCallback.updataOnlineUser(onlineUser);
                    }

                } else if (json.getString("type").equals("message")) {
                    chatMessage = new ChatMessage(json.getString("type"),
                            json.getString("from"), json.getString("content"),
                            json.getString("time"));
                    mlist.add(chatMessage);
                    chatMessageAdapter.notifyDataSetChanged();
                }

                Log.d("time", mlist.toString());
            } catch (JSONException e) {
                e.printStackTrace();
            }

            chatlist.setSelection(chatMessageAdapter.getCount());//让ListView滑到最下面
          }
    }

    @Override
    public void onDestroy() {
        // 停止服务
        getActivity().unbindService(conn);
        // 注销广播
        getActivity().unregisterReceiver(msgReceiver);
        super.onDestroy();
    }
}

这样一个简单的聊天室功能就实现了直接上图
这里写图片描述

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值