Android beginners use WebSocket to communicate with the server

Only the basic communication function is realized, and no ServiceandHandle

Reference resources:
SpringBoot uses WebSocket (1)
Implementation of Android WebSocket long connection

achieve effect

insert image description here

Server

The core code is as follows

@ServerEndpoint("/test")
@Component
@Slf4j
public class WebSocketController {
    
    
    /**
     * 存放所有在线的客户端
     */
    private static Map<String, Session> clients = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(Session session) {
    
    
        log.info("有新的客户端连接了: {}", session.getId());
        //将新用户存入在线的组
        clients.put(session.getId(), session);
    }

    /**
     * 客户端关闭
     *
     * @param session session
     */
    @OnClose
    public void onClose(Session session) {
    
    
        log.info("有用户断开了, id为:{}", session.getId());
        //将掉线的用户移除在线的组里
        clients.remove(session.getId());
    }

    /**
     * 发生错误
     *
     * @param throwable e
     */
    @OnError
    public void onError(Throwable throwable) {
    
    
        throwable.printStackTrace();
    }

    /**
     * 收到客户端发来消息
     *
     * @param message 消息对象
     */
    @OnMessage
    public void onMessage(String message) {
    
    
        log.info("服务端收到客户端发来的消息: {}", message);
        // 将消息repead一下 发送给所有在线的Client
        this.sendAll(message + message);
    }

    /**
     * 群发消息
     *
     * @param message 消息内容
     */
    private void sendAll(String message) {
    
    
        for (Map.Entry<String, Session> sessionEntry : clients.entrySet()) {
    
    
            sessionEntry.getValue().getAsyncRemote().sendText(message);
        }
    }
}

The effect of using PostMan test is shown in the following figure:
insert image description here

Android client

The first step is to add dependencies

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'org.java-websocket:Java-WebSocket:1.5.2'

The second step is to grant network permissions in the manifest file

<uses-permission android:name="android.permission.INTERNET"/>

The third step is to create ViewModel

public class MyViewModel extends ViewModel {
    
    
    private final MutableLiveData<String> mName = new MutableLiveData<>();
    private final MutableLiveData<String> mMsg = new MutableLiveData<>();
    // getter...
}

The fourth step is to write the page

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <variable
                name="viewModel"
                type="work.wxmx.socketclient.MyViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MainActivity">

        <EditText
                android:hint="Msg"
                android:layout_width="215dp"
                android:layout_height="49dp"
                android:inputType="textPersonName"
                android:text="@={viewModel.msg}"
                android:ems="10"
                android:id="@+id/msg_edit_text"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintHorizontal_bias="0.9"
                app:layout_constraintVertical_bias="1.0"
                app:layout_constraintEnd_toStartOf="@+id/send_button"
                app:layout_constraintStart_toEndOf="@+id/name_edit_text"
                android:layout_marginBottom="40dp" />

        <Button
                android:text="Send"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/send_button"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
                android:layout_marginEnd="8dp"
                app:layout_constraintVertical_bias="1.0"
                android:layout_marginRight="8dp"
                android:layout_marginBottom="40dp" />

        <EditText
                android:text="@={viewModel.name}"
                android:layout_width="80dp"
                android:layout_height="42dp"
                android:inputType="textPersonName"
                android:hint="Name"
                android:ems="10"
                android:id="@+id/name_edit_text"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
                android:layout_marginBottom="40dp"
                android:layout_marginLeft="10dp"
                android:layout_marginStart="10dp" />

        <TextView
                android:text="AAA"
                android:textSize="30sp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/msg_text_view"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                android:layout_marginTop="50dp" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

The effect diagram is shown in the figure below:
insert image description here

The fifth step is to implement WebSockClient

public class MyWebSocket extends WebSocketClient {
    
    
    private static final String TAG = "TAG";
    private SocketListener mSocketListener;

    public MyWebSocket(URI serverUri) {
    
    
        super(serverUri);
    }

    public MyWebSocket(URI serverUri, Draft protocolDraft) {
    
    
        super(serverUri, protocolDraft);
    }

    @Override
    public void onOpen(ServerHandshake handshakedata) {
    
    
        Log.e(TAG, "onOpen: ");
    }

    @Override
    public void onMessage(String message) {
    
    
        mSocketListener.onMessage(message);
    }

    @Override
    public void onClose(int code, String reason, boolean remote) {
    
    
        Log.e(TAG, "onClose: ");
    }

    @Override
    public void onError(Exception ex) {
    
    
        ex.printStackTrace();
        Log.e(TAG, "onError: ");
    }

    public interface SocketListener {
    
    
        void onMessage(String msg);
    }

    public SocketListener getSocketListener() {
    
    
        return mSocketListener;
    }

    public void setSocketListener(SocketListener socketListener) {
    
    
        mSocketListener = socketListener;
    }
}

The sixth step is to write Activity

public class MainActivity extends AppCompatActivity {
    
    
    private static final String TAG = "TAG";
    ActivityMainBinding mBinding;
    MyViewModel mViewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        mBinding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(mBinding.getRoot());
        mViewModel = new ViewModelProvider(this).get(MyViewModel.class);
        mBinding.setViewModel(mViewModel);
        URI uri = URI.create("ws://10.0.2.2:8080/test");
        MyWebSocket webSocket = new MyWebSocket(uri);
        webSocket.setSocketListener(mSocketListener);
        try {
    
    
            boolean b = webSocket.connectBlocking(4, TimeUnit.SECONDS);
            Log.e(TAG, "onCreate: " + b);
            if (b) {
    
    

            } else {
    
    
            }
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        mBinding.sendButton.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View view) {
    
    
                if (webSocket.isOpen()) {
    
    
                    String name = mViewModel.getName().getValue();
                    String msg = mViewModel.getMsg().getValue();
                    String sendData = name +msg;
                    Log.e(TAG, "onClick: " + sendData);
                    webSocket.send(sendData);
                } else {
    
    
                    webSocket.reconnect();
                    Log.e(TAG, "onClick: web socket is not open");
                }
            }
        });
    }

    private MyWebSocket.SocketListener mSocketListener = new MyWebSocket.SocketListener() {
    
    
        @Override
        public void onMessage(String msg) {
    
    
            Log.e(TAG, "onMessage: " + msg);
            mBinding.msgTextView.setText(mBinding.msgTextView.getText() + "" + msg);
        }
    };
}

End Peace!

Guess you like

Origin blog.csdn.net/qq_41359651/article/details/119631944