欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android之okhttp实现socket通讯(非原创)

程序员文章站 2022-03-22 12:02:42
文章大纲 一、okhttp基础介绍二、socket通讯代码实战三、项目源码下载四、参考文章 一、okhttp基础介绍 https://www.jianshu.com/p/e3291b7808e7 二、socket通讯代码实战 1. 添加依赖和权限 app的build.gradle下添加okhttp依 ......

文章大纲

一、okhttp基础介绍
二、socket通讯代码实战
三、项目源码下载
四、参考文章

 
Android之okhttp实现socket通讯(非原创)

一、okhttp基础介绍

二、socket通讯代码实战

1. 添加依赖和权限

app的build.gradle下添加okhttp依赖

implementation 'com.squareup.okhttp3:okhttp:3.8.1'
 
Android之okhttp实现socket通讯(非原创)

androidmanifest.xml文件添加网络权限

<uses-permission  android:name="android.permission.internet" />
 
Android之okhttp实现socket通讯(非原创)

2. 添加布局文件

activity_main.xml文件中代码如下:

<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <button
        android:id="@+id/start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="start"
        android:textsize="16sp" />

    <textview
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <button
        android:id="@+id/start2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="start2"
        android:textsize="16sp" />

    <textview
        android:id="@+id/text2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</linearlayout>

3. mainactivity逻辑实现

package aidl_customer.com.wj.http_socket;

import android.support.v7.app.appcompatactivity;
import android.os.bundle;
import android.view.view;
import android.widget.button;
import android.widget.textview;

import java.util.concurrent.timeunit;

import okhttp3.okhttpclient;
import okhttp3.request;
import okhttp3.response;
import okhttp3.websocket;
import okhttp3.websocketlistener;
import okio.bytestring;

/**
 * okhttp是3.5以后才添加对websocket的支持
 */
public class mainactivity extends appcompatactivity {

    private button start;
    private textview text;

    private button start2;
    private textview text2;

    @override
    protected void oncreate(bundle savedinstancestate) {
        super.oncreate(savedinstancestate);
        setcontentview(r.layout.activity_main);

        start = (button) findviewbyid(r.id.start);
        text = (textview) findviewbyid(r.id.text);

        start2 = (button) findviewbyid(r.id.start2);
        text2 = (textview) findviewbyid(r.id.text2);

        start.setonclicklistener(new view.onclicklistener() {
            @override
            public void onclick(view v) {

                connect();
            }
        });

        start2.setonclicklistener(new view.onclicklistener() {
            @override
            public void onclick(view v) {

                okhttpclient  client = new okhttpclient.builder()
                        .readtimeout(3, timeunit.seconds)
                        .build();


                request request = new request.builder()
                        .url("ws://echo.websocket.org")
                        .build();
                websocket websocket = client.newwebsocket(request, new websocketlistener() {
                    @override
                    public void onopen(websocket websocket, response response) {
                        super.onopen(websocket, response);
                    }

                    @override
                    public void onmessage(websocket websocket, string text) {
                        super.onmessage(websocket, text);
                    }

                    @override
                    public void onmessage(websocket websocket, bytestring bytes) {
                        super.onmessage(websocket, bytes);
                    }

                    @override
                    public void onclosing(websocket websocket, int code, string reason) {
                        super.onclosing(websocket, code, reason);
                    }

                    @override
                    public void onclosed(websocket websocket, int code, string reason) {
                        super.onclosed(websocket, code, reason);
                    }

                    @override
                    public void onfailure(websocket websocket, throwable t, response response) {
                        super.onfailure(websocket, t, response);
                    }
                });
            }
        });
    }

    /**
     *websocket官网就提供了相应url可以测试
     */
    private void connect() {

        //建立连接
        echowebsocketlistener listener = new echowebsocketlistener();
        request request = new request.builder()
                .url("ws://echo.websocket.org")
                .build();
        okhttpclient client = new okhttpclient();
        client.newwebsocket(request, listener);

        client.dispatcher().executorservice().shutdown();
    }

    /**
     * 重写了websocketlistener中的几个方法,这几个方法很好理解,是用来异步回调的,
     * 这里简单说一下:onopen当websocket和远程建立连接时回调;两个onmessage就是接收到消息时回调,
     * 只是消息内容的类型不同;onclosing是当远程端暗示没有数据交互时回调(即此时准备关闭,但连接还没有关闭);
     * onclosed就是当连接已经释放的时候被回调;onfailure当然是失败时被回调(包括连接失败,发送失败等)。
     *
     * send用来发送消息;close用来关闭连接
     */
    private final class echowebsocketlistener extends websocketlistener {

        @override
        public void onopen(websocket websocket, response response) {

            websocket.send("hello world");
            websocket.send("welcome");
            websocket.send(bytestring.decodehex("adef"));
            websocket.close(1000, "再见");
        }

        @override
        public void onmessage(websocket websocket, string text) {
            output("onmessage: " + text);
        }

        @override
        public void onmessage(websocket websocket, bytestring bytes) {
            output("onmessage bytestring: " + bytes);
        }

        @override
        public void onclosing(websocket websocket, int code, string reason) {
            websocket.close(1000, null);
            output("onclosing: " + code + "/" + reason);
        }

        @override
        public void onclosed(websocket websocket, int code, string reason) {
            output("onclosed: " + code + "/" + reason);
        }

        @override
        public void onfailure(websocket websocket, throwable t, response response) {
            output("onfailure: " + t.getmessage());
        }
    }

    private void output(final string content) {

        runonuithread(new runnable() {
            @override
            public void run() {
                text.settext(text.gettext().tostring() + content + "\n");
            }
        });
    }
}

温馨提示:
(1)echowebsocketlistener继承okhttp中的抽象类websocketlistener,重写了几个方法,是用来异步回调的,这里简单说一下:onopen当websocket和远程建立连接时回调;两个onmessage就是接收到消息时回调,只是消息内容的类型不同;onclosing是当远程端暗示没有数据交互时回调(即此时准备关闭,但连接还没有关闭);onclosed就是当连接已经释放的时候被回调;onfailure当然是失败时被回调(包括连接失败,发送失败等)。
(2)send用来发送消息;close用来关闭连接
(3)websocket官网就提供了相应url可以测试,测试地址为:ws://echo.websocket.org
(4)关闭连接方式,okhttp提供两个方法来关闭连接:
  1)close websocket.close(0, “bye”);请求服务器优雅地关闭连接然后等待确认。在关闭之前,所有已经在队列中的消息将被传送完毕。 既然涉及到交互,那么socket可能不会立即关闭。如果初始化和关闭连接是和activity的生命周期绑定的(比如onpause/onresume),有一些消息可能是在close被调用之后接收到,所以这需要小心去处理。
  2)cancel;cancel更加残忍:它会丢弃所有已经在队列中的消息然后残忍地关闭socket。这样也有优点:不必等待家政(housekeeping)和已在队列中消息的传送。然而,选择cancel还是close取决于使用场景。

4. 项目运行与访问

安装apk后,运行主页面如下:

 
Android之okhttp实现socket通讯(非原创)

点击start按钮,出现以下结果

 
Android之okhttp实现socket通讯(非原创)

三、项目源码下载

链接:https://pan.baidu.com/s/1t8omzy8wlzr2aki8s2xcwq
提取码:jwzi

四、参考文章

    1. https://blog.csdn.net/xlh1191860939/article/details/75452342/
    2. https://blog.csdn.net/xlh1191860939/article/details/75452513