WebSocket实现Android客户端之间的简单通讯

xiaoxiao2021-02-28  63

作为一个刚毕业的程序猴,自觉的自己能力比较欠缺,正好最近公司没有什么项目,就考虑自己动手做个项目。想来想去,就把自己一直想做的即时通讯拿出来做做。可是问题来了,作为一个Android开发人员,一直没有接触后台的人来说,做一个完整的项目还是比较麻烦的。于是只有边学边做了。

对于通讯来说,我对Websocket情有独钟,可能是因为在学校的时候听说过吧。话不多说,经过几天的调研,终于在搭了一个简单的Servlet+websocket服务器,并且能在android客户端上实现不同客户端之间的通讯。我想这是万里长征的第一步的成功吧。话不多说,进入正题。

效果图如下:

Android端这里使用的是Autobahn的包,支持Android 使用Websocket,下载地址:http://autobahn.ws/android/downloads/;

具体与服务器的连接方法WebSocketConnection. Connect()方法,通过WebSocketHandler进行与服务器连接通讯。里面的具体方法不再详述。

与不同的客户端进行通讯的思路为:

Step1:在连接成功的时候,向服务器发送自己的用户名,服务器做用户标记;

Step2: 发送消息,格式为“XX@XXX”,@前面表示将要发送的对象,“all”表示群发,@后面表示发送的消息。

Step3: 当然不能忘了网路权限。

 

 

Android端的只有代码如下:

[java]  view plain  copy 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);       }          /**       * websocket连接,接收服务器消息       */       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 : "");   //                    mConnect.sendTextMessage("I am android client");                   }                      @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();       }          /**       * 发送消息       *       * @param msg       */       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;主要是对于客户端连接的用户进行处理与标记,并且根据客户端的要求向不同对象转发消息,实现不同客户端之间的通讯。具体代码如下:

[java]  view plain  copy import javax.websocket.*;   import javax.websocket.server.ServerEndpoint;   import java.io.IOException;   import java.util.HashMap;   import java.util.concurrent.CopyOnWriteArraySet;      /**   * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,   * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端   */   @ServerEndpoint("/websocketServer")   public class WebSocketTest {          //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。       private static int onlineCount = 0;          //connect key为session的ID,value为此对象this       private static final HashMap<String, Object> connect = new HashMap<String, Object>();       //userMap key为session的ID,value为用户名       private static final HashMap<String, String> userMap = new HashMap<String, String>();       //与某个客户端的连接会话,需要通过它来给客户端发送数据       private Session session;       //判断是否是第一次接收的消息       private boolean isfirst = true;          private String username;          /**       * 连接建立成功调用的方法       *       * @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据       */       @OnOpen       public void onOpen(Session session) {           this.session = session;           connect.put(session.getId(), this);//获取Session,存入Hashmap中       }          /**       * 连接关闭调用的方法       */       @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());       }          /**       * 收到客户端消息后调用的方法       *       * @param message 客户端发送过来的消息       * @param session 可选的参数       */       @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);//以@为分隔符把字符串分为xxx和xxxxx两部分,msg[0]表示发送至的用户名,all则表示发给所有人               if (msg[0].equals("all")) {                   sendToAll(msg[1], session);               } else {                   sendToUser(msg[0], msg[1], session);               }           }       }          /**       * 发生错误时调用       *       * @param session       * @param error       */       @OnError       public void onError(Session session, Throwable error) {           System.out.println("发生错误");           error.printStackTrace();       }          /**       * 给所有人发送消息       *       * @param msg     发送的消息       * @param session       */       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();                       }                   }               }              }       }          /**       * 发送给指定用户       *       * @param user    用户名       * @param msg     发送的消息       * @param session       */       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;//找到指定用户标记为true                   break;               }              }           //you为true则在自己页面显示自己对xxx说xxxxx,否则显示系统:无此用户           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;

转载请注明原文地址: https://www.6miu.com/read-82387.html

最新回复(0)