WebSocket实现Android客户端之间的简单通讯
来源:互联网 发布:linux 发送arp包 编辑:程序博客网 时间:2024/06/06 11:42
作为一个刚毕业的程序猴,自觉的自己能力比较欠缺,正好最近公司没有什么项目,就考虑自己动手做个项目。想来想去,就把自己一直想做的即时通讯拿出来做做。可是问题来了,作为一个Android开发人员,一直没有接触后台的人来说,做一个完整的项目还是比较麻烦的。于是只有边学边做了。
对于通讯来说,我对Websocket情有独钟,可能是因为在学校的时候听说过吧。话不多说,经过几天的调研,终于在搭了一个简单的Servlet+websocket服务器,并且能在android客户端上实现不同客户端之间的通讯。我想这是万里长征的第一步的成功吧。话不多说,进入正题。
效果图如下:
Android端这里使用的是Autobahn的包,支持Android 使用Websocket,下载地址:http://autobahn.ws/android/downloads/;
具体与服务器的连接方法WebSocketConnection. Connect()方法,通过WebSocketHandler进行与服务器连接通讯。里面的具体方法不再详述。
与不同的客户端进行通讯的思路为:
Step1:在连接成功的时候,向服务器发送自己的用户名,服务器做用户标记;
Step2: 发送消息,格式为“XX@XXX”,@前面表示将要发送的对象,“all”表示群发,@后面表示发送的消息。
Step3: 当然不能忘了网路权限。
Android端的只有代码如下:
- package henry.websocket.test;
-
- import android.support.v7.app.AppCompatActivity;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.View;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.TextView;
- import android.widget.Toast;
-
- import de.tavendo.autobahn.WebSocketConnection;
- import de.tavendo.autobahn.WebSocketException;
- import de.tavendo.autobahn.WebSocketHandler;
-
- public class MainActivity extends AppCompatActivity implements View.OnClickListener {
-
- private static final String wsurl = "ws://172.16.50.126:8080/websocketServer";
- private static final String TAG = "MainActivity";
- private WebSocketConnection mConnect = new WebSocketConnection();
- private EditText mContent;
- private Button mSend;
- private TextView mText;
- private EditText mUserName;
- private EditText mToSb;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- bindObject();
- connect();
- }
-
-
-
-
- private void bindObject() {
- mContent = (EditText) findViewById(R.id.et_content);
- mSend = (Button) findViewById(R.id.btn_send);
- mText = (TextView) findViewById(R.id.tv_test);
- mUserName = (EditText) findViewById(R.id.et_username);
- mToSb = (EditText) findViewById(R.id.et_to);
- mSend.setOnClickListener(this);
- }
-
-
-
-
- private void connect() {
- Log.i(TAG, "ws connect....");
- try {
- mConnect.connect(wsurl, new WebSocketHandler() {
- @Override
- public void onOpen() {
- Log.i(TAG, "Status:Connect to " + wsurl);
- sendUsername();
- }
-
- @Override
- public void onTextMessage(String payload) {
- Log.i(TAG, payload);
- mText.setText(payload != null ? payload : "");
-
- }
-
- @Override
- public void onClose(int code, String reason) {
- Log.i(TAG, "Connection lost..");
- }
- });
- } catch (WebSocketException e) {
- e.printStackTrace();
- }
- }
-
-
-
-
- private void sendUsername() {
- String user = mUserName.getText().toString();
- if (user != null && user.length() != 0)
- mConnect.sendTextMessage(user);
- else
- Toast.makeText(getApplicationContext(), "不能为空", Toast.LENGTH_SHORT).show();
- }
-
-
-
-
-
-
- private void sendMessage(String msg) {
- if (mConnect.isConnected()) {
- mConnect.sendTextMessage(msg);
- } else {
- Log.i(TAG, "no connection!!");
- }
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mConnect.disconnect();
- }
-
- @Override
- public void onClick(View view) {
- if (view == mSend) {
- String content = mToSb.getText().toString() + "@" + mContent.getText().toString();
- if (content != null && content.length() != 0)
- sendMessage(content);
- else
- Toast.makeText(getApplicationContext(), "不能为空", Toast.LENGTH_SHORT).show();
- }
- }
- }
服务器端主要是借鉴别人的,具体见http://www.mobile-open.com/2016/968477.html;主要是对于客户端连接的用户进行处理与标记,并且根据客户端的要求向不同对象转发消息,实现不同客户端之间的通讯。具体代码如下:
- import javax.websocket.*;
- import javax.websocket.server.ServerEndpoint;
- import java.io.IOException;
- import java.util.HashMap;
- import java.util.concurrent.CopyOnWriteArraySet;
-
-
-
-
-
- @ServerEndpoint("/websocketServer")
- public class WebSocketTest {
-
-
- private static int onlineCount = 0;
-
-
- private static final HashMap<String, Object> connect = new HashMap<String, Object>();
-
- private static final HashMap<String, String> userMap = new HashMap<String, String>();
-
- private Session session;
-
- private boolean isfirst = true;
-
- private String username;
-
-
-
-
-
-
- @OnOpen
- public void onOpen(Session session) {
- this.session = session;
- connect.put(session.getId(), this);
- }
-
-
-
-
- @OnClose
- public void onClose(Session session) {
-
- String usr = userMap.get(session.getId());
- userMap.remove(session.getId());
- connect.remove(session.getId());
-
-
- System.out.println(usr + "退出!当前在线人数为" + connect.size());
- }
-
-
-
-
-
-
-
- @OnMessage
- public void onMessage(String message, Session session) {
-
- if (isfirst) {
- this.username = message;
- System.out.println("用户" + username + "上线,在线人数:" + connect.size());
- userMap.put(session.getId(), username);
- isfirst = false;
- } else {
- String[] msg = message.split("@", 2);
- if (msg[0].equals("all")) {
- sendToAll(msg[1], session);
- } else {
- sendToUser(msg[0], msg[1], session);
- }
- }
- }
-
-
-
-
-
-
-
- @OnError
- public void onError(Session session, Throwable error) {
- System.out.println("发生错误");
- error.printStackTrace();
- }
-
-
-
-
-
-
-
- private void sendToAll(String msg, Session session) {
- String who = "";
-
- for (String key : connect.keySet()) {
- WebSocketTest client = (WebSocketTest) connect.get(key);
- if (key.equalsIgnoreCase(userMap.get(key))) {
- who = "自己对大家说 : ";
- } else {
- who = userMap.get(session.getId()) + "对大家说 :";
- }
- synchronized (client) {
- try {
- client.session.getBasicRemote().sendText(who + msg);
- } catch (IOException e) {
- connect.remove(client);
- e.printStackTrace();
- try {
- client.session.close();
- } catch (IOException e1) {
- e1.printStackTrace();
- }
- }
- }
-
- }
- }
-
-
-
-
-
-
-
-
- private void sendToUser(String user, String msg, Session session) {
- boolean you = false;
- for (String key : userMap.keySet()) {
- if (user.equalsIgnoreCase(userMap.get(key))) {
- WebSocketTest client = (WebSocketTest) connect.get(key);
- synchronized (client) {
- try {
- client.session.getBasicRemote().sendText(userMap.get(session.getId()) + "对你说:" + msg);
- } catch (IOException e) {
- connect.remove(client);
- try {
- client.session.close();
- } catch (IOException e1) {
- e1.printStackTrace();
- }
- }
- }
- you = true;
- break;
- }
-
- }
-
- if (you) {
- try {
- session.getBasicRemote().sendText("自己对" + user + "说:" + msg);
- } catch (IOException e) {
- e.printStackTrace();
- }
- } else {
- try {
- session.getBasicRemote().sendText("系统:无此用户");
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- }
-
- }
虽然实现了简单的通讯,但要做成一个完整的项目,这还远远不够,下面要考虑的东西还很多。
代码地址:http://download.csdn.net/detail/henry__mark/9637322;