From 163d778e683a0761ef3c2a68daf3e07c8a7c70a9 Mon Sep 17 00:00:00 2001 From: Changhua Date: Mon, 17 Oct 2022 22:16:08 +0800 Subject: [PATCH] Add java client --- java/README.MD | 13 ++ java/pom.xml | 77 ++++++++++ .../src/main/java/com/iamteer/wcf/Client.java | 144 ++++++++++++++++++ java/src/main/java/com/iamteer/wcf/Main.java | 64 ++++++++ proto/wcf.proto | 1 + 5 files changed, 299 insertions(+) create mode 100644 java/README.MD create mode 100644 java/pom.xml create mode 100644 java/src/main/java/com/iamteer/wcf/Client.java create mode 100644 java/src/main/java/com/iamteer/wcf/Main.java diff --git a/java/README.MD b/java/README.MD new file mode 100644 index 0000000..d94c924 --- /dev/null +++ b/java/README.MD @@ -0,0 +1,13 @@ +# WeChatFerry Java 客户端 +## 配置环境 +选择 32 位的 JDK [temurin](https://adoptium.net/zh-CN/temurin/releases)。 + +## 重新生成 gRPC 文件 +[gRPC 文件生成工具](https://repo.maven.apache.org/maven2/io/grpc/protoc-gen-grpc-java/)。 +```sh +cd java/src/main/java/ +protoc --java_out=. -I=../../../../proto wcf.proto +protoc --grpc-java_out=. --plugin=protoc-gen-grpc-java="C:/Tools/bin/protoc-gen-grpc-java-1.49.2-windows-x86_32.exe" -I=../../../../proto wcf.proto +``` + +`C:/Tools/bin` 为工具存放路径。 diff --git a/java/pom.xml b/java/pom.xml new file mode 100644 index 0000000..1318de0 --- /dev/null +++ b/java/pom.xml @@ -0,0 +1,77 @@ + + + 4.0.0 + + com.iamteer.demo + gRpcDemo + 1.0-SNAPSHOT + + + + kr.motd.maven + os-maven-plugin + 1.6.2 + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 17 + 17 + + + + org.xolstice.maven.plugins + protobuf-maven-plugin + 0.6.1 + + com.google.protobuf:protoc:3.21.7:exe:${os.detected.classifier} + grpc-java + io.grpc:protoc-gen-grpc-java:1.50.0:exe:${os.detected.classifier} + + + + + compile + compile-custom + + + + + + + + + net.java.dev.jna + jna + 5.3.1 + + + io.grpc + grpc-netty-shaded + 1.50.0 + runtime + + + io.grpc + grpc-protobuf + 1.50.0 + + + io.grpc + grpc-stub + 1.50.0 + + + org.apache.tomcat + annotations-api + 6.0.53 + provided + + + + \ No newline at end of file diff --git a/java/src/main/java/com/iamteer/wcf/Client.java b/java/src/main/java/com/iamteer/wcf/Client.java new file mode 100644 index 0000000..666415e --- /dev/null +++ b/java/src/main/java/com/iamteer/wcf/Client.java @@ -0,0 +1,144 @@ +package com.iamteer.wcf; + +import java.util.List; +import java.util.Map; +import com.sun.jna.Library; +import com.sun.jna.Native; + +import io.grpc.ManagedChannel; +import io.grpc.stub.StreamObserver; +import io.grpc.ManagedChannelBuilder; + +public class Client { + private interface JnaLibrary extends Library { + JnaLibrary INSTANCE = Native.load("sdk", JnaLibrary.class); + + void WxInitSDK(); + + void WxDestroySDK(); + } + + public void InitClient(String hostPort) { + JnaLibrary.INSTANCE.WxInitSDK(); + this.connect(hostPort); + } + + public void CleanupClient() { + this.DisableRecvMsg(); + JnaLibrary.INSTANCE.WxDestroySDK(); + } + + private void connect(String hostPort) { + ManagedChannel managedChannel = ManagedChannelBuilder.forTarget(hostPort) + .usePlaintext() + .build(); + this.wcfBlokingStub = WcfGrpc.newBlockingStub(managedChannel); + this.wcfStub = WcfGrpc.newStub(managedChannel); + } + + public int IsLogin() { + WcfOuterClass.Empty empty = WcfOuterClass.Empty.newBuilder().build(); + WcfOuterClass.Response response = this.wcfBlokingStub.rpcIsLogin(empty); + return response.getStatus(); + } + + public String GetSelfWxid() { + WcfOuterClass.Empty empty = WcfOuterClass.Empty.newBuilder().build(); + WcfOuterClass.String rsp = this.wcfBlokingStub.rpcGetSelfWxid(empty); + return rsp.getStr(); + } + + public void EnableRecvMsg() { + if (isReceivingMsg) { + return; + } + + isReceivingMsg = true; + WcfOuterClass.Empty empty = WcfOuterClass.Empty.newBuilder().build(); + this.wcfStub.rpcEnableRecvMsg(empty, new StreamObserver() { + @Override + public void onNext(WcfOuterClass.WxMsg value) { + System.out.printf("New Message:\n%s", value); + } + + @Override + public void onError(Throwable t) { + System.err.println("EnableRecvMsg Error"); + } + + @Override + public void onCompleted() { + System.out.println("EnableRecvMsg Complete"); + } + }); + } + + public int DisableRecvMsg() { + if (!isReceivingMsg) { + return 0; + } + + WcfOuterClass.Empty empty = WcfOuterClass.Empty.newBuilder().build(); + WcfOuterClass.Response response = this.wcfBlokingStub.rpcDisableRecvMsg(empty); + if (response.getStatus() == 0) { + isReceivingMsg = false; + return 0; + } + + return -1; + } + + public int SendText(String msg, String receiver, String aters) { + WcfOuterClass.TextMsg textMsg = WcfOuterClass.TextMsg.newBuilder().setMsg(msg).setReceiver(receiver) + .setAters(aters).build(); + WcfOuterClass.Response response = this.wcfBlokingStub.rpcSendTextMsg(textMsg); + return response.getStatus(); + } + + public int SendImage(String path, String receiver) { + WcfOuterClass.ImageMsg imageMsg = WcfOuterClass.ImageMsg.newBuilder().setPath(path).setReceiver(receiver) + .build(); + WcfOuterClass.Response response = this.wcfBlokingStub.rpcSendImageMsg(imageMsg); + return response.getStatus(); + } + + public Map GetMsgTypes() { + WcfOuterClass.Empty empty = WcfOuterClass.Empty.newBuilder().build(); + WcfOuterClass.MsgTypes msgTypes = this.wcfBlokingStub.rpcGetMsgTypes(empty); + return msgTypes.getTypesMap(); + } + + public List GetContacts() { + WcfOuterClass.Empty empty = WcfOuterClass.Empty.newBuilder().build(); + WcfOuterClass.Contacts contacts = this.wcfBlokingStub.rpcGetContacts(empty); + return contacts.getContactsList(); + } + + public List GetDbs() { + WcfOuterClass.Empty empty = WcfOuterClass.Empty.newBuilder().build(); + WcfOuterClass.DbNames dbs = this.wcfBlokingStub.rpcGetDbNames(empty); + return dbs.getNamesList(); + } + + public List GetTables(String db) { + WcfOuterClass.String str = WcfOuterClass.String.newBuilder().setStr(db).build(); + WcfOuterClass.DbTables tables = this.wcfBlokingStub.rpcGetDbTables(str); + return tables.getTablesList(); + } + + public List QuerySql(String db, String sql) { + WcfOuterClass.DbQuery query = WcfOuterClass.DbQuery.newBuilder().setDb(db).setSql(sql).build(); + WcfOuterClass.DbRows rows = this.wcfBlokingStub.rpcExecDbQuery(query); + return rows.getRowsList(); + } + + public int AcceptNewFriend(String v3, String v4) { + WcfOuterClass.Verification v = WcfOuterClass.Verification.newBuilder().setV3(v3).setV4(v4).build(); + WcfOuterClass.Response response = this.wcfBlokingStub.rpcAcceptNewFriend(v); + return response.getStatus(); + } + + private boolean isReceivingMsg = false; + private WcfGrpc.WcfBlockingStub wcfBlokingStub; + private WcfGrpc.WcfStub wcfStub; +} diff --git a/java/src/main/java/com/iamteer/wcf/Main.java b/java/src/main/java/com/iamteer/wcf/Main.java new file mode 100644 index 0000000..4b939be --- /dev/null +++ b/java/src/main/java/com/iamteer/wcf/Main.java @@ -0,0 +1,64 @@ +package com.iamteer.wcf; + +import java.util.List; +import java.util.Map; +import java.util.Iterator; + +public class Main { + public static void main(String[] args) throws Exception { + String hostPort = "localhost:10086"; + Client client = new Client(); + client.InitClient(hostPort); + System.out.println("Connecting to " + hostPort); + + int status = client.IsLogin(); + System.out.println(status); + + String wxid = client.GetSelfWxid(); + System.out.println(wxid); + + client.EnableRecvMsg(); // Receive Message + + Map msgTypes = client.GetMsgTypes(); + Iterator> iterTypes = msgTypes.entrySet().iterator(); + while (iterTypes.hasNext()) { + Map.Entry entry = iterTypes.next(); + System.out.println(entry.getKey() + ": " + entry.getValue()); + } + + List contacts = client.GetContacts(); + Iterator iterContacts = contacts.iterator(); + while (iterContacts.hasNext()) { + WcfOuterClass.Contact contact = iterContacts.next(); + System.out.println(contact); + } + + List dbs = client.GetDbs(); + Iterator iterDbs = dbs.iterator(); + while (iterDbs.hasNext()) { + String db = iterDbs.next(); + System.out.println(db); + } + + List tables = client.GetTables("MicroMsg.db"); + Iterator iterTables = tables.iterator(); + while (iterTables.hasNext()) { + WcfOuterClass.DbTable table = iterTables.next(); + System.out.println(table); + } + + List rows = client.QuerySql("MicroMsg.db", "SELECT * FROM Contact LIMIT 1;"); + Iterator iterRows = rows.iterator(); + while (iterRows.hasNext()) { + WcfOuterClass.DbRow row = iterRows.next(); + System.out.println(row); + } + + // status = client.AcceptNewFriend("v3", "v4"); // 需要真实的数据 + // System.out.println(status); + + Thread.sleep(1000); + client.CleanupClient(); + } + +} diff --git a/proto/wcf.proto b/proto/wcf.proto index b327bf8..b2c2ed7 100644 --- a/proto/wcf.proto +++ b/proto/wcf.proto @@ -1,6 +1,7 @@ syntax = "proto3"; package wcf; +option java_package = "com.iamteer.wcf"; service Wcf { rpc RpcIsLogin(Empty) returns (Response) {}