Add java client

This commit is contained in:
Changhua 2022-10-17 22:16:08 +08:00
parent 9fef73f9c2
commit 163d778e68
5 changed files with 299 additions and 0 deletions

13
java/README.MD Normal file
View File

@ -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` 为工具存放路径。

77
java/pom.xml Normal file
View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.iamteer.demo</groupId>
<artifactId>gRpcDemo</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.2</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.21.7:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.50.0:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.3.1</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.50.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.50.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.50.0</version>
</dependency>
<dependency> <!-- necessary for Java 9+ -->
<groupId>org.apache.tomcat</groupId>
<artifactId>annotations-api</artifactId>
<version>6.0.53</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -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<WcfOuterClass.WxMsg>() {
@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<Integer, String> GetMsgTypes() {
WcfOuterClass.Empty empty = WcfOuterClass.Empty.newBuilder().build();
WcfOuterClass.MsgTypes msgTypes = this.wcfBlokingStub.rpcGetMsgTypes(empty);
return msgTypes.getTypesMap();
}
public List<WcfOuterClass.Contact> GetContacts() {
WcfOuterClass.Empty empty = WcfOuterClass.Empty.newBuilder().build();
WcfOuterClass.Contacts contacts = this.wcfBlokingStub.rpcGetContacts(empty);
return contacts.getContactsList();
}
public List<String> GetDbs() {
WcfOuterClass.Empty empty = WcfOuterClass.Empty.newBuilder().build();
WcfOuterClass.DbNames dbs = this.wcfBlokingStub.rpcGetDbNames(empty);
return dbs.getNamesList();
}
public List<WcfOuterClass.DbTable> GetTables(String db) {
WcfOuterClass.String str = WcfOuterClass.String.newBuilder().setStr(db).build();
WcfOuterClass.DbTables tables = this.wcfBlokingStub.rpcGetDbTables(str);
return tables.getTablesList();
}
public List<WcfOuterClass.DbRow> 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;
}

View File

@ -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<Integer, String> msgTypes = client.GetMsgTypes();
Iterator<Map.Entry<Integer, String>> iterTypes = msgTypes.entrySet().iterator();
while (iterTypes.hasNext()) {
Map.Entry<Integer, String> entry = iterTypes.next();
System.out.println(entry.getKey() + ": " + entry.getValue());
}
List<WcfOuterClass.Contact> contacts = client.GetContacts();
Iterator<WcfOuterClass.Contact> iterContacts = contacts.iterator();
while (iterContacts.hasNext()) {
WcfOuterClass.Contact contact = iterContacts.next();
System.out.println(contact);
}
List<String> dbs = client.GetDbs();
Iterator<String> iterDbs = dbs.iterator();
while (iterDbs.hasNext()) {
String db = iterDbs.next();
System.out.println(db);
}
List<WcfOuterClass.DbTable> tables = client.GetTables("MicroMsg.db");
Iterator<WcfOuterClass.DbTable> iterTables = tables.iterator();
while (iterTables.hasNext()) {
WcfOuterClass.DbTable table = iterTables.next();
System.out.println(table);
}
List<WcfOuterClass.DbRow> rows = client.QuerySql("MicroMsg.db", "SELECT * FROM Contact LIMIT 1;");
Iterator<WcfOuterClass.DbRow> 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();
}
}

View File

@ -1,6 +1,7 @@
syntax = "proto3";
package wcf;
option java_package = "com.iamteer.wcf";
service Wcf {
rpc RpcIsLogin(Empty) returns (Response) {}