feat(0): [java]-[wcferry-mvn]-架构调整
This commit is contained in:
parent
12029ebba0
commit
fed590cdc6
@ -1,17 +0,0 @@
|
||||
package com.iamteer;
|
||||
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@Data
|
||||
@Order(100)
|
||||
public class BussinessContext {
|
||||
|
||||
private Client client;
|
||||
|
||||
}
|
94
clients/java/wcferry-mvn/src/main/java/com/iamteer/config/WechatConfiguration.java
vendored
Normal file
94
clients/java/wcferry-mvn/src/main/java/com/iamteer/config/WechatConfiguration.java
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
package com.iamteer.config;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import com.iamteer.handle.WechatSocketClient;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 配置类-注入微信客户端
|
||||
*
|
||||
* @author chandler
|
||||
* @date 2024-09-30 12:21
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class WechatConfiguration {
|
||||
|
||||
@Resource
|
||||
private WcferryProperties properties;
|
||||
|
||||
@Bean
|
||||
public WechatSocketClient client() {
|
||||
log.debug("测试:端口:{},地址:{}", properties.getSocketPort(), properties.getDllPath());
|
||||
// 连接远程 RPC
|
||||
// Client client = new Client("127.0.0.1", 10086);
|
||||
|
||||
// 本地启动 RPC
|
||||
// Client client = new Client(); // 默认 10086 端口
|
||||
// Client client = new Client(10088,true); // 也可以指定端口
|
||||
WechatSocketClient wechatSocketClient = new WechatSocketClient(properties.getSocketPort(), properties.getDllPath());
|
||||
|
||||
// 是否已登录
|
||||
// log.info("isLogin: {}", client.isLogin());
|
||||
|
||||
// 登录账号 wxid
|
||||
// log.info("wxid: {}", client.getSelfWxid());
|
||||
|
||||
// 消息类型
|
||||
// log.info("message types: {}", client.getMsgTypes());
|
||||
|
||||
// 所有联系人(包括群聊、公众号、好友……)
|
||||
// client.printContacts(client.getContacts());
|
||||
|
||||
// 获取数据库
|
||||
log.info("dbs: {}", wechatSocketClient.getDbNames());
|
||||
|
||||
// 获取数据库下的表
|
||||
String db = "MicroMsg.db";
|
||||
// log.info("tables in {}: {}", db, client.getDbTables(db));
|
||||
|
||||
// 发送文本消息,aters 是要 @ 的 wxid,多个用逗号分隔;消息里@的数量要与aters里的数量对应
|
||||
// client.sendText("Hello", "filehelper", "");
|
||||
// client.sendText("Hello @某人1 @某人2", "xxxxxxxx@chatroom", "wxid_xxxxxxxxxxxxx1,wxid_xxxxxxxxxxxxx2");
|
||||
|
||||
// 发送图片消息,图片必须要存在
|
||||
// client.sendImage("C:\\Projs\\WeChatFerry\\TEQuant.jpeg", "filehelper");
|
||||
|
||||
// 发送文件消息,文件必须要存在
|
||||
// client.sendFile("C:\\Projs\\WeChatFerry\\README.MD", "filehelper");
|
||||
|
||||
String xml =
|
||||
"<?xml version=\"1.0\"?><msg><appmsg appid=\"\" sdkver=\"0\"><title>叮当药房,24小时服务,28分钟送药到家!</title><des>叮当快药首家承诺范围内28分钟送药到家!叮当快药核心区域内7*24小时全天候服务,送药上门!叮当快药官网为您提供快捷便利,正品低价,安全放心的购药、送药服务体验。</des><action>view</action><type>33</type><showtype>0</showtype><content /><url>https://mp.weixin.qq.com/mp/waerrpage?appid=wxc2edadc87077fa2a&type=upgrade&upgradetype=3#wechat_redirect</url><dataurl /><lowurl /><lowdataurl /><recorditem /><thumburl /><messageaction /><md5>7f6f49d301ebf47100199b8a4fcf4de4</md5><extinfo /><sourceusername>gh_c2b88a38c424@app</sourceusername><sourcedisplayname>叮当快药 药店送药到家夜间买药</sourcedisplayname><commenturl /><appattach><totallen>0</totallen><attachid /><emoticonmd5></emoticonmd5><fileext>jpg</fileext><filekey>da0e08f5c7259d03da150d5e7ca6d950</filekey><cdnthumburl>3057020100044b30490201000204e4c0232702032f4ef20204a6bace6f02046401f62d042430326337303430352d333734332d343362652d623335322d6233333566623266376334620204012400030201000405004c537600</cdnthumburl><aeskey>0db26456caf243fbd4efb99058a01d66</aeskey><cdnthumbaeskey>0db26456caf243fbd4efb99058a01d66</cdnthumbaeskey><encryver>1</encryver><cdnthumblength>61558</cdnthumblength><cdnthumbheight>100</cdnthumbheight><cdnthumbwidth>100</cdnthumbwidth></appattach><weappinfo><pagepath>pages/index/index.html</pagepath><username>gh_c2b88a38c424@app</username><appid>wxc2edadc87077fa2a</appid><version>197</version><type>2</type><weappiconurl>http://wx.qlogo.cn/mmhead/Q3auHgzwzM4727n0NQ0ZIPQPlfp15m1WLsnrXbo1kLhFGcolgLyc0A/96</weappiconurl><appservicetype>0</appservicetype><shareId>1_wxc2edadc87077fa2a_29177e9a9b918cb9e75964f80bb8f32e_1677849476_0</shareId></weappinfo><websearch /></appmsg><fromusername>wxid_eob5qfcrv4zd22</fromusername><scene>0</scene><appinfo><version>1</version><appname /></appinfo><commenturl /></msg>";
|
||||
// client.sendXml("filehelper", xml, "", 0x21);
|
||||
|
||||
// 发送表情消息,gif 必须要存在
|
||||
// client.sendEmotion("C:\\Projs\\WeChatFerry\\emo.gif", "filehelper");
|
||||
|
||||
// 接收消息,并调用 printWxMsg 处理
|
||||
wechatSocketClient.enableRecvMsg(100);
|
||||
Thread thread = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
while (wechatSocketClient.getIsReceivingMsg()) {
|
||||
wechatSocketClient.printWxMsg(wechatSocketClient.getMsg());
|
||||
}
|
||||
}
|
||||
});
|
||||
thread.start();
|
||||
// client.diableRecvMsg(); // 需要停止时调用
|
||||
|
||||
wechatSocketClient.keepRunning();
|
||||
|
||||
new Thread(new Runnable() {
|
||||
public void run() {
|
||||
wechatSocketClient.keepRunning();
|
||||
}
|
||||
}).start();
|
||||
|
||||
return wechatSocketClient;
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.iamteer;
|
||||
package com.iamteer.handle;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
@ -34,9 +34,9 @@ import io.sisu.nng.pair.Pair1Socket;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class Client {
|
||||
public class WechatSocketClient {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(Client.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(WechatSocketClient.class);
|
||||
private static final int BUFFER_SIZE = 16 * 1024 * 1024; // 16M
|
||||
private Socket cmdSocket = null;
|
||||
private Socket msgSocket = null;
|
||||
@ -52,15 +52,15 @@ public class Client {
|
||||
private int port;
|
||||
private String dllPath;
|
||||
|
||||
public Client() {
|
||||
public WechatSocketClient() {
|
||||
this(DEFAULT_HOST, PORT, false, DEFAULT_DLL_PATH);
|
||||
}
|
||||
|
||||
public Client(int port, String dllPath) {
|
||||
public WechatSocketClient(int port, String dllPath) {
|
||||
this(DEFAULT_HOST, port, false, dllPath);
|
||||
}
|
||||
|
||||
public Client(String host, int port, boolean debug, String dllPath) {
|
||||
public WechatSocketClient(String host, int port, boolean debug, String dllPath) {
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.dllPath = dllPath;
|
@ -1,105 +0,0 @@
|
||||
package com.iamteer.runner;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.iamteer.BussinessContext;
|
||||
import com.iamteer.Client;
|
||||
import com.iamteer.config.WcferryProperties;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 启动回调-调用微信
|
||||
*
|
||||
* @author chandler
|
||||
* @date 2024-09-21 12:21
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@Order(101)
|
||||
public class WechatRunner implements ApplicationRunner {
|
||||
|
||||
@Resource
|
||||
private WcferryProperties properties;
|
||||
|
||||
@Resource
|
||||
private BussinessContext bussinessContext;
|
||||
|
||||
public WechatRunner(BussinessContext bussinessContext) {
|
||||
this.bussinessContext = bussinessContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
System.out.println(">>>服务启动第一个开始执行的任务<<<<");
|
||||
runWechat();
|
||||
}
|
||||
|
||||
private void runWechat() {
|
||||
log.debug("测试:端口:{},地址:{}", properties.getSocketPort(), properties.getDllPath());
|
||||
// 连接远程 RPC
|
||||
// Client client = new Client("127.0.0.1", 10086);
|
||||
|
||||
// 本地启动 RPC
|
||||
// Client client = new Client(); // 默认 10086 端口
|
||||
// Client client = new Client(10088,true); // 也可以指定端口
|
||||
Client client = new Client(properties.getSocketPort(), properties.getDllPath());
|
||||
bussinessContext.setClient(client); // 默认 10086 端口
|
||||
|
||||
// 是否已登录
|
||||
// log.info("isLogin: {}", client.isLogin());
|
||||
|
||||
// 登录账号 wxid
|
||||
// log.info("wxid: {}", client.getSelfWxid());
|
||||
|
||||
// 消息类型
|
||||
// log.info("message types: {}", client.getMsgTypes());
|
||||
|
||||
// 所有联系人(包括群聊、公众号、好友……)
|
||||
// client.printContacts(client.getContacts());
|
||||
|
||||
// 获取数据库
|
||||
log.info("dbs: {}", client.getDbNames());
|
||||
|
||||
// 获取数据库下的表
|
||||
String db = "MicroMsg.db";
|
||||
// log.info("tables in {}: {}", db, client.getDbTables(db));
|
||||
|
||||
// 发送文本消息,aters 是要 @ 的 wxid,多个用逗号分隔;消息里@的数量要与aters里的数量对应
|
||||
// client.sendText("Hello", "filehelper", "");
|
||||
// client.sendText("Hello @某人1 @某人2", "xxxxxxxx@chatroom", "wxid_xxxxxxxxxxxxx1,wxid_xxxxxxxxxxxxx2");
|
||||
|
||||
// 发送图片消息,图片必须要存在
|
||||
// client.sendImage("C:\\Projs\\WeChatFerry\\TEQuant.jpeg", "filehelper");
|
||||
|
||||
// 发送文件消息,文件必须要存在
|
||||
// client.sendFile("C:\\Projs\\WeChatFerry\\README.MD", "filehelper");
|
||||
|
||||
String xml =
|
||||
"<?xml version=\"1.0\"?><msg><appmsg appid=\"\" sdkver=\"0\"><title>叮当药房,24小时服务,28分钟送药到家!</title><des>叮当快药首家承诺范围内28分钟送药到家!叮当快药核心区域内7*24小时全天候服务,送药上门!叮当快药官网为您提供快捷便利,正品低价,安全放心的购药、送药服务体验。</des><action>view</action><type>33</type><showtype>0</showtype><content /><url>https://mp.weixin.qq.com/mp/waerrpage?appid=wxc2edadc87077fa2a&type=upgrade&upgradetype=3#wechat_redirect</url><dataurl /><lowurl /><lowdataurl /><recorditem /><thumburl /><messageaction /><md5>7f6f49d301ebf47100199b8a4fcf4de4</md5><extinfo /><sourceusername>gh_c2b88a38c424@app</sourceusername><sourcedisplayname>叮当快药 药店送药到家夜间买药</sourcedisplayname><commenturl /><appattach><totallen>0</totallen><attachid /><emoticonmd5></emoticonmd5><fileext>jpg</fileext><filekey>da0e08f5c7259d03da150d5e7ca6d950</filekey><cdnthumburl>3057020100044b30490201000204e4c0232702032f4ef20204a6bace6f02046401f62d042430326337303430352d333734332d343362652d623335322d6233333566623266376334620204012400030201000405004c537600</cdnthumburl><aeskey>0db26456caf243fbd4efb99058a01d66</aeskey><cdnthumbaeskey>0db26456caf243fbd4efb99058a01d66</cdnthumbaeskey><encryver>1</encryver><cdnthumblength>61558</cdnthumblength><cdnthumbheight>100</cdnthumbheight><cdnthumbwidth>100</cdnthumbwidth></appattach><weappinfo><pagepath>pages/index/index.html</pagepath><username>gh_c2b88a38c424@app</username><appid>wxc2edadc87077fa2a</appid><version>197</version><type>2</type><weappiconurl>http://wx.qlogo.cn/mmhead/Q3auHgzwzM4727n0NQ0ZIPQPlfp15m1WLsnrXbo1kLhFGcolgLyc0A/96</weappiconurl><appservicetype>0</appservicetype><shareId>1_wxc2edadc87077fa2a_29177e9a9b918cb9e75964f80bb8f32e_1677849476_0</shareId></weappinfo><websearch /></appmsg><fromusername>wxid_eob5qfcrv4zd22</fromusername><scene>0</scene><appinfo><version>1</version><appname /></appinfo><commenturl /></msg>";
|
||||
// client.sendXml("filehelper", xml, "", 0x21);
|
||||
|
||||
// 发送表情消息,gif 必须要存在
|
||||
// client.sendEmotion("C:\\Projs\\WeChatFerry\\emo.gif", "filehelper");
|
||||
|
||||
// 接收消息,并调用 printWxMsg 处理
|
||||
client.enableRecvMsg(100);
|
||||
Thread thread = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
while (client.getIsReceivingMsg()) {
|
||||
client.printWxMsg(client.getMsg());
|
||||
}
|
||||
}
|
||||
});
|
||||
thread.start();
|
||||
// client.diableRecvMsg(); // 需要停止时调用
|
||||
|
||||
client.keepRunning();
|
||||
}
|
||||
|
||||
}
|
@ -2,11 +2,12 @@ package com.iamteer.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.iamteer.BussinessContext;
|
||||
import com.iamteer.handle.WechatSocketClient;
|
||||
import com.iamteer.service.TestService;
|
||||
import com.iamteer.utils.SpringContextHolderUtil;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@ -20,16 +21,17 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Service
|
||||
public class TestServiceImpl implements TestService {
|
||||
|
||||
@Resource
|
||||
private WechatSocketClient wechatSocketClient;
|
||||
|
||||
@Override
|
||||
public Boolean isLogin() {
|
||||
|
||||
BussinessContext bussinessContext = SpringContextHolderUtil.getBean(BussinessContext.class);
|
||||
|
||||
boolean flag = bussinessContext.getClient().isLogin();
|
||||
boolean flag = wechatSocketClient.isLogin();
|
||||
log.info("flag:{}", flag);
|
||||
List<String> list = bussinessContext.getClient().getDbNames();
|
||||
List<String> list = wechatSocketClient.getDbNames();
|
||||
log.info("list:{}", list);
|
||||
return flag;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,173 +0,0 @@
|
||||
package com.iamteer.utils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.GenericBeanDefinition;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Spring 工具类
|
||||
*
|
||||
* @author chandler
|
||||
* @date 2023-03-30 11:05:49
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@Lazy(false)
|
||||
public class SpringContextHolderUtil implements ApplicationContextAware, DisposableBean {
|
||||
|
||||
/**
|
||||
* 上下文对象实例
|
||||
*/
|
||||
private static ApplicationContext applicationContext = null;
|
||||
|
||||
/**
|
||||
* 获取applicationContext-取得存储在静态变量中的ApplicationContext.
|
||||
*/
|
||||
public static ApplicationContext getApplicationContext() {
|
||||
checkApplicationContext();
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 实现ApplicationContextAware接口, 注入Context到静态变量中.
|
||||
*/
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) {
|
||||
SpringContextHolderUtil.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过name获取Bean-从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T getBean(String name) {
|
||||
checkApplicationContext();
|
||||
if (applicationContext.containsBean(name)) {
|
||||
return (T)applicationContext.getBean(name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过class获取Bean-从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
|
||||
*/
|
||||
public static <T> T getBean(Class<T> requiredType) {
|
||||
checkApplicationContext();
|
||||
return applicationContext.getBean(requiredType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过name,以及Clazz返回指定的Bean
|
||||
*/
|
||||
public static <T> T getBean(String name, Class<T> requiredType) {
|
||||
return getApplicationContext().getBean(name, requiredType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
|
||||
*/
|
||||
public static <T> T getBeanOfType(Class<T> clazz) {
|
||||
checkApplicationContext();
|
||||
return (T)applicationContext.getBeansOfType(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除SpringContextHolder中的ApplicationContext为Null.
|
||||
*/
|
||||
public static void clearHolder() {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext);
|
||||
}
|
||||
applicationContext = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布事件
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
public static void publishEvent(ApplicationEvent event) {
|
||||
if (applicationContext == null) {
|
||||
return;
|
||||
}
|
||||
applicationContext.publishEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* 实现DisposableBean接口, 在Context关闭时清理静态变量.
|
||||
*/
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void destroy() {
|
||||
SpringContextHolderUtil.clearHolder();
|
||||
}
|
||||
|
||||
public static synchronized void registerSingletonBean(String beanName, Class clzz, Map<String, Object> original) {
|
||||
checkApplicationContext();
|
||||
DefaultListableBeanFactory beanFactory =
|
||||
(DefaultListableBeanFactory)SpringContextHolderUtil.getApplicationContext().getAutowireCapableBeanFactory();
|
||||
if (beanFactory.containsBean(beanName)) {
|
||||
removeBean(beanName);
|
||||
}
|
||||
GenericBeanDefinition definition = new GenericBeanDefinition();
|
||||
// 类class
|
||||
definition.setBeanClass(clzz);
|
||||
// 属性赋值
|
||||
definition.setPropertyValues(new MutablePropertyValues(original));
|
||||
// 注册到spring上下文
|
||||
beanFactory.registerBeanDefinition(beanName, definition);
|
||||
}
|
||||
|
||||
public static synchronized void registerSingletonBean(String beanName, Object obj, Map<String, Object> original) {
|
||||
checkApplicationContext();
|
||||
DefaultListableBeanFactory beanFactory =
|
||||
(DefaultListableBeanFactory)SpringContextHolderUtil.getApplicationContext().getAutowireCapableBeanFactory();
|
||||
if (beanFactory.containsBean(beanName)) {
|
||||
removeBean(beanName);
|
||||
}
|
||||
GenericBeanDefinition definition = new GenericBeanDefinition();
|
||||
// 类class
|
||||
definition.setBeanClass(obj.getClass());
|
||||
// 属性赋值
|
||||
definition.setPropertyValues(new MutablePropertyValues(original));
|
||||
// 注册到spring上下文
|
||||
beanFactory.registerBeanDefinition(beanName, definition);
|
||||
}
|
||||
|
||||
public static synchronized void registerSingletonBean(String beanName, Object obj) {
|
||||
registerSingletonBean(beanName, obj, JSONObject.parseObject(JSON.toJSONString(obj), Map.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除spring中管理的bean
|
||||
*
|
||||
* @param beanName
|
||||
*/
|
||||
public static void removeBean(String beanName) {
|
||||
ApplicationContext ctx = SpringContextHolderUtil.getApplicationContext();
|
||||
DefaultListableBeanFactory acf = (DefaultListableBeanFactory)ctx.getAutowireCapableBeanFactory();
|
||||
if (acf.containsBean(beanName)) {
|
||||
acf.removeBeanDefinition(beanName);
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkApplicationContext() {
|
||||
if (applicationContext == null) {
|
||||
throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义SpringContextUtil");
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user