惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog
V
Vulnerabilities – Threatpost
Apple Machine Learning Research
Apple Machine Learning Research
V
V2EX
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志
人人都是产品经理
人人都是产品经理
Latest news
Latest news
博客园 - 三生石上(FineUI控件)
美团技术团队
aimingoo的专栏
aimingoo的专栏
Google Online Security Blog
Google Online Security Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
T
Threatpost
Y
Y Combinator Blog
T
Tailwind CSS Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
A
Arctic Wolf
C
Cyber Attacks, Cyber Crime and Cyber Security
小众软件
小众软件
Recent Commits to openclaw:main
Recent Commits to openclaw:main
T
Tenable Blog
W
WeLiveSecurity
L
LINUX DO - 热门话题
D
Docker
Cyberwarzone
Cyberwarzone
量子位
A
About on SuperTechFans
The Last Watchdog
The Last Watchdog
雷峰网
雷峰网
C
CERT Recently Published Vulnerability Notes
P
Palo Alto Networks Blog
The Hacker News
The Hacker News
Blog — PlanetScale
Blog — PlanetScale
P
Proofpoint News Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
F
Full Disclosure
The Cloudflare Blog
T
The Blog of Author Tim Ferriss
T
The Exploit Database - CXSecurity.com
Engineering at Meta
Engineering at Meta
O
OpenAI News
Hacker News - Newest:
Hacker News - Newest: "LLM"
Scott Helme
Scott Helme
IT之家
IT之家
S
Secure Thoughts
MongoDB | Blog
MongoDB | Blog
L
Lohrmann on Cybersecurity
博客园 - 司徒正美
Google DeepMind News
Google DeepMind News

LengYue's Blog

在 Android 中实现 iOS 液态玻璃效果(二:折射与渗透效果) | LengYue's Blog 在 Android 中实现 iOS 液态玻璃效果 | LengYue's Blog Dart 单线程模型的本质 | LengYue's Blog 使用 Rust 开发 Android 底层库,并简化 Java 与 Rust 相互操作 | LengYue's Blog 将 Rust 编译为可在 Android 上使用的二进制文件 | LengYue's Blog Flutter error not found dart html | LengYue's Blog AndroidStudio新版本Logcat | LengYue's Blog Typecho to Hugo | LengYue's Blog GetX Router 设置返回值 | LengYue's Blog Flutter 基础 | Dart 语法 mixin | LengYue's Blog 不使用第三方软件实现Obsidian多平台实时同步 | LengYue's Blog Android 使用字节码 hook 修复第三发 bug | LengYue's Blog 在 Jetpack Compose 中使用输入框(TextField )遇到的一些问题 | LengYue's Blog Android-使用@AutoService实现spi | LengYue's Blog RecyclerView使用优化的ListAdapter | LengYue's Blog ⾃定义布局流程 | LengYue's Blog ViewModel之自定义构造函数 | LengYue's Blog Android Jetpack Compose 超快速上手指南 | LengYue's Blog android 11 [api 30] 适配指南 | LengYue's Blog Android 声明式 UI 框架 Litho 初探 —— Sections API | LengYue's Blog Android 声明式 UI 框架 Litho 初探 —— Layout | LengYue's Blog Android声明式UI框架 Litho 初探 —— MountSpec的使用 | LengYue's Blog Android声明式UI框架 Litho 初探——基础使用 | LengYue's Blog Android声明式UI框架 Litho 初探 ——两种数据类型 | LengYue's Blog
使用 GoMobile 创建 Android、iOS 跨平台 WebSocket Library | LengYue's Blog
LengYue · 2023-03-14 · via LengYue's Blog

GoMobile 是 Go 语言的扩展,将 Go 代码编译为可在移动设备上运行的静态库或动态库,可在 iOS 和 Android 平台上使用。本文介绍如何使用 GoMobile 创建 Android 应用并在其中调用 Go 语言 WebSocket。

安装 GoMobile

go install golang.org/x/mobile/cmd/gomobile@latest

创建 Go WebSocket 库

首先创建一个 Go WebSocket 服务端:

mkdir go-websocket
cd go-websocket
go mod init go-socket
// 使用 gomobile 初始
gomobile init

如果你无法使用 gomobile init 请检查 GOBIN 是否加入环境变量 我们使用在 go 中广泛使用的 gorilla/websocket 来创建 websocket 服务端:

go get github.com/gorilla/websocket

编写 WebSocket 服务端代码:

package socket
import (
	"flag"
	"log"
	"net/http"
	"github.com/gorilla/websocket"
)
var addr = flag.String("addr", "localhost:8080", "http service address")
var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
} // use default options
func handleWebSocket(w http.ResponseWriter, r *http.Request) {
	c, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Print("upgrade:", err)
		return
	}
	defer c.Close()
	for {
		mt, message, err := c.ReadMessage()
		if err != nil {
			log.Println("read:", err)
			break
		}
		log.Printf("recv: %s", message)
		err = c.WriteMessage(mt, message)
		if err != nil {
			log.Println("write:", err)
			break
		}
	}
}
func main() {
	flag.Parse()
	log.SetFlags(0)
	http.HandleFunc("/", handleWebSocket)
	log.Fatal(http.ListenAndServe(*addr, nil))
}
func StartServer() {
	flag.Parse()
	log.SetFlags(0)
	http.HandleFunc("/", handleWebSocket)
	log.Fatal(http.ListenAndServe(*addr, nil))
}

上面这段代码我们使用 Gorilla WebSocket 库来处理 WebSocket 连接。当连接建立后,函数将在一个无限循环中等待来自客户端的消息,并将这些消息原封不动地发送回客户端。 我们可以运行 main 方法来测试 WebSocket 服务器是否正常运行。

构建 Go 库

现在,将我们的 Go 代码编译成一个静态库,以便它可以被 Android 应用程序使用:

 gomobile bind -target=android/arm64 -o go-websocket.aar -classpath com.apkdv.websocket 

- o 指定输出文件的名字。
-classpath 指定输出的类包名

创建 Android 应用程序

在 Android Studio 中创建一个新项目。选择 “Empty Activity” 模板。 将刚刚创建的 Go 库导入到 Android 项目中:

  • 将 go-websocket.aar 文件复制到 Android 项目的 libs 文件夹中。如果该文件夹不存在,则需要手动创建。
  • 在 App 的 build.gradle dependencies 下添加: api fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
  • 同时我们使用 okHttp 连接我们的 go-websocket 最终我们的 dependencies 如下: 接下来在 MainActivity 中使用 okhttp 连接 websocket 服务:
val request = Request.Builder()
            .url("ws://127.0.0.1:8080")
            .build()
        val client = OkHttpClient.Builder()
            .pingInterval(10, TimeUnit.SECONDS)
            .build()
        webSocket = client.newWebSocket(request, object : WebSocketListener() {
            override fun onOpen(webSocket: WebSocket, response: Response) {
                super.onOpen(webSocket, response)
                webSocket.send("Hello, server!")
            }
            override fun onMessage(webSocket: WebSocket, text: String) {
                super.onMessage(webSocket, text)
                Log.d(TAG, "Received message: $text")
            }
            override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
                super.onMessage(webSocket, bytes)
                Log.d(TAG, "Received message: ${bytes.utf8()}")
            }
            override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
                super.onFailure(webSocket, t, response)
                Log.d(TAG, "WebSocket connection failed: ${t.message}")
            }
        })

建立连接之后,点击按钮,发送一个每次递增的消息

findViewById<TextView>(R.id.text).setOnClickListener {
            index++
            webSocket.send("index $index")
        }

上面的代码。我们首先用 okhttp 连接 go 床架创建的 websocket 服务端,在连接成功后,点击屏幕上的按钮,会向服务端发送一个消息,服务端收到消息后,会将消息原封不动在发送回客户端。 来看看运行日志:

总结

使用 Go 开发跨平台 Library 需要一下步骤:

  • 安装 GoMobile,并使用 gomobile init 初始化 go 项目
  • 使用 GoMobile 将 go 项目编译常 android、iOS 的支持库
  • 将编译的 aar 导入项目
  • 在 Android 项目中使用 aar 借助 GoMobile 我们能简单方便的将 go 代码在移动端使用,下篇文章,我们将介绍如何将 Rust 集成到移动端,与 go 相比,Rust 有更更多的有点。