react-native-tcp-windows 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +145 -0
  3. package/lib/commonjs/ReactNativeTcpWindows.js +9 -0
  4. package/lib/commonjs/ReactNativeTcpWindows.js.map +1 -0
  5. package/lib/commonjs/index.js +124 -0
  6. package/lib/commonjs/index.js.map +1 -0
  7. package/lib/commonjs/package.json +1 -0
  8. package/lib/module/ReactNativeTcpWindows.js +5 -0
  9. package/lib/module/ReactNativeTcpWindows.js.map +1 -0
  10. package/lib/module/index.js +104 -0
  11. package/lib/module/index.js.map +1 -0
  12. package/lib/module/package.json +1 -0
  13. package/lib/typescript/commonjs/package.json +1 -0
  14. package/lib/typescript/commonjs/src/ReactNativeTcpWindows.d.ts +13 -0
  15. package/lib/typescript/commonjs/src/ReactNativeTcpWindows.d.ts.map +1 -0
  16. package/lib/typescript/commonjs/src/__tests__/index.test.d.ts +1 -0
  17. package/lib/typescript/commonjs/src/__tests__/index.test.d.ts.map +1 -0
  18. package/lib/typescript/commonjs/src/index.d.ts +80 -0
  19. package/lib/typescript/commonjs/src/index.d.ts.map +1 -0
  20. package/lib/typescript/module/package.json +1 -0
  21. package/lib/typescript/module/src/ReactNativeTcpWindows.d.ts +13 -0
  22. package/lib/typescript/module/src/ReactNativeTcpWindows.d.ts.map +1 -0
  23. package/lib/typescript/module/src/__tests__/index.test.d.ts +1 -0
  24. package/lib/typescript/module/src/__tests__/index.test.d.ts.map +1 -0
  25. package/lib/typescript/module/src/index.d.ts +80 -0
  26. package/lib/typescript/module/src/index.d.ts.map +1 -0
  27. package/package.json +204 -0
  28. package/react-native.config.js +12 -0
  29. package/src/ReactNativeTcpWindows.ts +14 -0
  30. package/src/__tests__/index.test.tsx +1 -0
  31. package/src/index.tsx +124 -0
  32. package/windows/ExperimentalFeatures.props +33 -0
  33. package/windows/ReactNativeTcpWindows/ReactNativeTcpWindows.cpp +206 -0
  34. package/windows/ReactNativeTcpWindows/ReactNativeTcpWindows.def +3 -0
  35. package/windows/ReactNativeTcpWindows/ReactNativeTcpWindows.h +83 -0
  36. package/windows/ReactNativeTcpWindows/ReactNativeTcpWindows.rc +0 -0
  37. package/windows/ReactNativeTcpWindows/ReactNativeTcpWindows.vcxproj +146 -0
  38. package/windows/ReactNativeTcpWindows/ReactNativeTcpWindows.vcxproj.filters +44 -0
  39. package/windows/ReactNativeTcpWindows/ReactPackageProvider.cpp +20 -0
  40. package/windows/ReactNativeTcpWindows/ReactPackageProvider.h +24 -0
  41. package/windows/ReactNativeTcpWindows/ReactPackageProvider.idl +9 -0
  42. package/windows/ReactNativeTcpWindows/TcpSocket.cpp +565 -0
  43. package/windows/ReactNativeTcpWindows/TcpSocket.h +69 -0
  44. package/windows/ReactNativeTcpWindows/codegen/.clang-format +2 -0
  45. package/windows/ReactNativeTcpWindows/codegen/NativeReactNativeTcpWindowsSpec.g.h +71 -0
  46. package/windows/ReactNativeTcpWindows/packages.lock.json +60 -0
  47. package/windows/ReactNativeTcpWindows/pch.cpp +1 -0
  48. package/windows/ReactNativeTcpWindows/pch.h +30 -0
  49. package/windows/ReactNativeTcpWindows/resource.h +5 -0
  50. package/windows/ReactNativeTcpWindows/targetver.h +8 -0
  51. package/windows/ReactNativeTcpWindows.sln +43 -0
package/package.json ADDED
@@ -0,0 +1,204 @@
1
+ {
2
+ "name": "react-native-tcp-windows",
3
+ "version": "0.2.0",
4
+ "description": "TCP sockets communication for RNW",
5
+ "source": "./src/index.tsx",
6
+ "main": "./lib/commonjs/index.js",
7
+ "module": "./lib/module/index.js",
8
+ "exports": {
9
+ ".": {
10
+ "import": {
11
+ "types": "./lib/typescript/module/src/index.d.ts",
12
+ "default": "./lib/module/index.js"
13
+ },
14
+ "require": {
15
+ "types": "./lib/typescript/commonjs/src/index.d.ts",
16
+ "default": "./lib/commonjs/index.js"
17
+ }
18
+ },
19
+ "./package.json": "./package.json"
20
+ },
21
+ "files": [
22
+ "src",
23
+ "lib",
24
+ "cpp",
25
+ "react-native.config.js",
26
+ "windows"
27
+ ],
28
+ "scripts": {
29
+ "example": "yarn workspace react-native-tcp-windows-example",
30
+ "test": "jest",
31
+ "typecheck": "tsc",
32
+ "lint": "eslint \"**/*.{js,ts,tsx}\"",
33
+ "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
34
+ "prepare": "bob build",
35
+ "codegen": "react-native codegen-windows",
36
+ "release": "release-it"
37
+ },
38
+ "keywords": [
39
+ "react-native",
40
+ "react-native-windows",
41
+ "tcp"
42
+ ],
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "git+https://github.com/KGGrande/react-native-tcp-windows.git"
46
+ },
47
+ "author": "Kyle Grande <KGGrande@hormel.com> (https://github.com/KGGrande)",
48
+ "license": "MIT",
49
+ "bugs": {
50
+ "url": "https://github.com/KGGrande/react-native-tcp-windows/issues"
51
+ },
52
+ "homepage": "https://github.com/KGGrande/react-native-tcp-windows#readme",
53
+ "publishConfig": {
54
+ "registry": "https://registry.npmjs.org/"
55
+ },
56
+ "devDependencies": {
57
+ "@commitlint/config-conventional": "^19.6.0",
58
+ "@evilmartians/lefthook": "^1.5.0",
59
+ "@react-native-community/cli": "18.0.0",
60
+ "@react-native/eslint-config": "^0.73.1",
61
+ "@release-it/conventional-changelog": "^9.0.2",
62
+ "@types/jest": "^29.5.5",
63
+ "@types/react": "^19.0.0",
64
+ "commitlint": "^19.6.1",
65
+ "del-cli": "^5.1.0",
66
+ "eslint": "^8.51.0",
67
+ "eslint-config-prettier": "^9.0.0",
68
+ "eslint-plugin-prettier": "^5.0.1",
69
+ "jest": "^29.7.0",
70
+ "prettier": "^3.0.3",
71
+ "react": "19.0.0",
72
+ "react-native": "0.79.0",
73
+ "react-native-builder-bob": "^0.38.3",
74
+ "react-native-windows": "0.79.0",
75
+ "release-it": "^17.10.0",
76
+ "turbo": "^1.10.7",
77
+ "typescript": "^5.2.2"
78
+ },
79
+ "peerDependencies": {
80
+ "react": "*",
81
+ "react-native": "*",
82
+ "react-native-windows": "*"
83
+ },
84
+ "workspaces": [
85
+ "example"
86
+ ],
87
+ "packageManager": "yarn@3.6.1",
88
+ "jest": {
89
+ "preset": "react-native",
90
+ "modulePathIgnorePatterns": [
91
+ "<rootDir>/example/node_modules",
92
+ "<rootDir>/lib/"
93
+ ]
94
+ },
95
+ "commitlint": {
96
+ "extends": [
97
+ "@commitlint/config-conventional"
98
+ ]
99
+ },
100
+ "release-it": {
101
+ "git": {
102
+ "commitMessage": "chore: release ${version}",
103
+ "tagName": "v${version}"
104
+ },
105
+ "npm": {
106
+ "publish": true
107
+ },
108
+ "github": {
109
+ "release": true
110
+ },
111
+ "plugins": {
112
+ "@release-it/conventional-changelog": {
113
+ "preset": {
114
+ "name": "angular"
115
+ }
116
+ }
117
+ }
118
+ },
119
+ "eslintConfig": {
120
+ "root": true,
121
+ "extends": [
122
+ "@react-native",
123
+ "prettier"
124
+ ],
125
+ "rules": {
126
+ "react/react-in-jsx-scope": "off",
127
+ "prettier/prettier": [
128
+ "error",
129
+ {
130
+ "quoteProps": "consistent",
131
+ "singleQuote": true,
132
+ "tabWidth": 2,
133
+ "trailingComma": "es5",
134
+ "useTabs": false
135
+ }
136
+ ]
137
+ }
138
+ },
139
+ "eslintIgnore": [
140
+ "node_modules/",
141
+ "lib/"
142
+ ],
143
+ "prettier": {
144
+ "quoteProps": "consistent",
145
+ "singleQuote": true,
146
+ "tabWidth": 2,
147
+ "trailingComma": "es5",
148
+ "useTabs": false
149
+ },
150
+ "react-native-builder-bob": {
151
+ "source": "src",
152
+ "output": "lib",
153
+ "targets": [
154
+ [
155
+ "module",
156
+ {
157
+ "esm": true
158
+ }
159
+ ],
160
+ [
161
+ "commonjs",
162
+ {
163
+ "esm": true
164
+ }
165
+ ],
166
+ [
167
+ "typescript",
168
+ {
169
+ "project": "tsconfig.build.json"
170
+ }
171
+ ]
172
+ ]
173
+ },
174
+ "codegenConfig": {
175
+ "name": "ReactNativeTcpWindowsSpec",
176
+ "type": "modules",
177
+ "jsSrcsDir": "src",
178
+ "outputDir": {
179
+ "ios": "ios/generated",
180
+ "android": "android/generated"
181
+ },
182
+ "android": {
183
+ "javaPackageName": "com.tcpwindows"
184
+ },
185
+ "includesGeneratedCode": true,
186
+ "windows": {
187
+ "namespace": "ReactNativeTcpWindowsCodegen",
188
+ "outputDirectory": "windows/ReactNativeTcpWindows/codegen",
189
+ "separateDataTypes": false
190
+ }
191
+ },
192
+ "create-react-native-library": {
193
+ "type": "turbo-module",
194
+ "languages": "kotlin-objc",
195
+ "version": "0.48.9"
196
+ },
197
+ "react-native-windows": {
198
+ "init-windows": {
199
+ "name": "ReactNativeTcpWindows",
200
+ "namespace": "ReactNativeTcpWindows",
201
+ "template": "cpp-lib"
202
+ }
203
+ }
204
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @type {import('@react-native-community/cli-types').UserDependencyConfig}
3
+ */
4
+ module.exports = {
5
+ dependency: {
6
+ platforms: {
7
+ android: {
8
+ cmakeListsPath: 'generated/jni/CMakeLists.txt',
9
+ },
10
+ },
11
+ },
12
+ };
@@ -0,0 +1,14 @@
1
+ import type { TurboModule } from 'react-native';
2
+ import { TurboModuleRegistry } from 'react-native';
3
+
4
+ export interface Spec extends TurboModule {
5
+ connectToServer(address: string, port: number): Promise<string>;
6
+ startServer(port: number): Promise<string>;
7
+ closeConnection(): Promise<string>;
8
+ write(data: Array<number>): Promise<boolean>;
9
+ getConnectionStatus(): Promise<boolean>;
10
+ addListener(eventType: string): void;
11
+ removeListeners(count: number): void;
12
+ }
13
+
14
+ export default TurboModuleRegistry.getEnforcing<Spec>('ReactNativeTcpWindows');
@@ -0,0 +1 @@
1
+ it.todo('write a test');
package/src/index.tsx ADDED
@@ -0,0 +1,124 @@
1
+ import { NativeEventEmitter } from 'react-native';
2
+ import TcpSocketWindows from './ReactNativeTcpWindows';
3
+
4
+ export const eventEmitter = new NativeEventEmitter(TcpSocketWindows);
5
+ export { TcpSocketWindows };
6
+ // Event types for better type safety
7
+ export const TCP_SOCKET_EVENTS = {
8
+ DATA_RECEIVED: 'TcpSocketDataReceived',
9
+ CLIENT_CONNECTED: 'TcpSocketClientConnected',
10
+ CLIENT_DISCONNECTED: 'TcpSocketClientDisconnected',
11
+ CONNECTION_STATUS_CHANGED: 'TcpSocketConnectionStatusChanged',
12
+ } as const;
13
+
14
+ export type TcpSocketEvent =
15
+ (typeof TCP_SOCKET_EVENTS)[keyof typeof TCP_SOCKET_EVENTS];
16
+
17
+ // Event data interfaces
18
+ export interface DataReceivedEvent {
19
+ data: number[];
20
+ }
21
+
22
+ export interface ClientConnectedEvent {
23
+ clientAddress: string;
24
+ }
25
+
26
+ export interface ClientDisconnectedEvent {
27
+ clientAddress: string;
28
+ }
29
+
30
+ export interface ConnectionStatusChangedEvent {
31
+ connected: boolean;
32
+ message: string;
33
+ }
34
+
35
+ /**
36
+ * Connect to a TCP server as a client
37
+ * @param address Server IP address (e.g., "192.168.1.100")
38
+ * @param port Server port number
39
+ * @returns Promise that resolves with success message
40
+ */
41
+ export function connectToServer(
42
+ address: string,
43
+ port: number
44
+ ): Promise<string> {
45
+ return TcpSocketWindows.connectToServer(address, port);
46
+ }
47
+
48
+ /**
49
+ * Start a TCP server to accept client connections
50
+ * @param port Port number to listen on
51
+ * @returns Promise that resolves with success message
52
+ */
53
+ export function startServer(port: number): Promise<string> {
54
+ return TcpSocketWindows.startServer(port);
55
+ }
56
+
57
+ /**
58
+ * Close the current connection (client or server)
59
+ * @returns Promise that resolves with success message
60
+ */
61
+ export function closeConnection(): Promise<string> {
62
+ return TcpSocketWindows.closeConnection();
63
+ }
64
+
65
+ /**
66
+ * Write data to the TCP connection
67
+ * For clients: sends to the connected server
68
+ * For servers: sends to all connected clients
69
+ * @param data Array of bytes to send (0-255)
70
+ * @returns Promise that resolves with success status
71
+ */
72
+ export function write(data: number[]): Promise<boolean> {
73
+ return TcpSocketWindows.write(data);
74
+ }
75
+
76
+ /**
77
+ * Get the current connection status
78
+ * @returns Promise that resolves with connection status object
79
+ */
80
+ export function getConnectionStatus(): Promise<boolean> {
81
+ return TcpSocketWindows.getConnectionStatus();
82
+ }
83
+
84
+ /**
85
+ * Write a string as UTF-8 bytes
86
+ * @param text String to send
87
+ * @returns Promise that resolves with success status
88
+ */
89
+ export function writeString(text: string): Promise<boolean> {
90
+ const encoder = new TextEncoder();
91
+ const bytes = Array.from(encoder.encode(text));
92
+ return write(bytes);
93
+ }
94
+
95
+ /**
96
+ * Write JSON data as UTF-8 bytes
97
+ * @param data Object to serialize and send
98
+ * @returns Promise that resolves with success status
99
+ */
100
+ export function writeJson(data: any): Promise<boolean> {
101
+ const jsonString = JSON.stringify(data);
102
+ return writeString(jsonString);
103
+ }
104
+
105
+ /**
106
+ * Convenience function to convert received byte array to string
107
+ * @param data Byte array from DataReceivedEvent
108
+ * @returns Decoded UTF-8 string
109
+ */
110
+ export function bytesToString(data: number[]): string {
111
+ const uint8Array = new Uint8Array(data);
112
+ const decoder = new TextDecoder();
113
+ return decoder.decode(uint8Array);
114
+ }
115
+
116
+ /**
117
+ * Convenience function to convert received byte array to JSON
118
+ * @param data Byte array from DataReceivedEvent
119
+ * @returns Parsed JSON object
120
+ */
121
+ export function bytesToJson(data: number[]): any {
122
+ const jsonString = bytesToString(data);
123
+ return JSON.parse(jsonString);
124
+ }
@@ -0,0 +1,33 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3
+
4
+ <PropertyGroup Label="Microsoft.ReactNative Experimental Features">
5
+ <!--
6
+ Required for building a New Architecture project.
7
+
8
+ Library projects can change this value to test against Old and New
9
+ Architectures when building the library project's local sln file.
10
+
11
+ Otherwise this value will be decided by the consuming RNW app.
12
+
13
+ See https://microsoft.github.io/react-native-windows/docs/new-architecture
14
+ -->
15
+ <RnwNewArch>true</RnwNewArch>
16
+
17
+ <!--
18
+ Changes compilation to assume use of Microsoft.ReactNative NuGet packages
19
+ instead of building the framework from source. Defaults to true.
20
+
21
+ This is set during library project creation and is used when building
22
+ the library project's local sln file.
23
+
24
+ Otherwise this value will be decided by the consuming RNW app.
25
+
26
+ See https://microsoft.github.io/react-native-windows/docs/nuget
27
+ -->
28
+ <UseExperimentalNuget>true</UseExperimentalNuget>
29
+
30
+ <ReactExperimentalFeaturesSet>true</ReactExperimentalFeaturesSet>
31
+ </PropertyGroup>
32
+
33
+ </Project>
@@ -0,0 +1,206 @@
1
+ #include "pch.h"
2
+ #include "ReactNativeTcpWindows.h"
3
+ #include "TcpSocket.h"
4
+ namespace winrt::ReactNativeTcpWindows
5
+ {
6
+
7
+ // See https://microsoft.github.io/react-native-windows/docs/native-platform for help writing native modules
8
+
9
+ void ReactNativeTcpWindows::Initialize(React::ReactContext const &reactContext) noexcept {
10
+ m_context = reactContext;
11
+ OutputDebugStringA("ReactNativeTcpWindows::Initialize called\n");
12
+ // m_tcpSocket = std::make_unique<TcpSocket>("127.0.0.1", 1234, TcpSocket::ConnectionType::Client);
13
+ if (m_tcpSocket) {
14
+ m_tcpSocket->close();
15
+ m_tcpSocket.reset();
16
+ OutputDebugStringA("Existing TcpSocket instance closed during Initialize\n");
17
+ }
18
+ }
19
+
20
+ ReactNativeTcpWindows::~ReactNativeTcpWindows() {
21
+ OutputDebugStringA("ReactNativeTcpWindows destructor called\n");
22
+
23
+ if (m_tcpSocket) {
24
+ m_tcpSocket->close(); // Calls TcpSocket::close
25
+ m_tcpSocket.reset(); // Triggers TcpSocket destructor
26
+ }
27
+ }
28
+
29
+ // double ReactNativeTcpWindows::multiply(double a, double b) noexcept {
30
+ // return a * b;
31
+ // }
32
+ void ReactNativeTcpWindows::connectToServer(std::string address, double port,
33
+ React::ReactPromise<std::string> &&promise) noexcept {
34
+ try {
35
+ OutputDebugStringA(("Connecting to TCP server:\n"
36
+ "Address: " + address + "\n"
37
+ "Port: " + std::to_string(static_cast<int>(port)) + "\n").c_str());
38
+
39
+ // Close existing connection if any
40
+ if (m_tcpSocket) {
41
+ m_tcpSocket->close();
42
+ m_tcpSocket.reset();
43
+ }
44
+
45
+ m_tcpSocket = std::make_unique<TcpSocket>(address, static_cast<int>(port), TcpSocket::ConnectionType::Client);
46
+
47
+ // Set up callbacks
48
+ m_tcpSocket->setDataReceivedCallback([this](const std::vector<uint8_t>& data) {
49
+ OnDataReceived(data);
50
+ });
51
+
52
+ m_tcpSocket->setConnectionStatusCallback([this, promise](bool connected, const std::string& message) {
53
+ OnConnectionStatusChanged(connected, message);
54
+ if (connected) {
55
+ promise.Resolve("Connected to server successfully");
56
+ } else {
57
+ promise.Reject(React::ReactError{"Error", message});
58
+ }
59
+ });
60
+
61
+ // Attempt connection
62
+ if (!m_tcpSocket->connect()) {
63
+ promise.Reject(React::ReactError{"Error", "Failed to initiate connection"});
64
+ }
65
+ // Note: Promise will be resolved/rejected in the connection status callback
66
+
67
+ } catch (const std::exception& e) {
68
+ promise.Reject(React::ReactError{"Error", e.what()});
69
+ }
70
+ }
71
+
72
+ void ReactNativeTcpWindows::startServer(double port,
73
+ React::ReactPromise<std::string> &&promise) noexcept {
74
+ try {
75
+ OutputDebugStringA(("Starting TCP server on port: " + std::to_string(static_cast<int>(port)) + "\n").c_str());
76
+
77
+ // Close existing connection if any
78
+ if (m_tcpSocket) {
79
+ m_tcpSocket->close();
80
+ m_tcpSocket.reset();
81
+ }
82
+
83
+ m_tcpSocket = std::make_unique<TcpSocket>("0.0.0.0", static_cast<int>(port), TcpSocket::ConnectionType::Server);
84
+
85
+ // Set up callbacks
86
+ m_tcpSocket->setDataReceivedCallback([this](const std::vector<uint8_t>& data) {
87
+ OnDataReceived(data);
88
+ });
89
+
90
+ m_tcpSocket->setClientConnectedCallback([this](const std::string& clientAddress) {
91
+ OnClientConnected(clientAddress);
92
+ });
93
+
94
+ m_tcpSocket->setClientDisconnectedCallback([this](const std::string& clientAddress) {
95
+ OnClientDisconnected(clientAddress);
96
+ });
97
+
98
+ m_tcpSocket->setConnectionStatusCallback([this](bool connected, const std::string& message) {
99
+ OnConnectionStatusChanged(connected, message);
100
+ });
101
+
102
+ if (m_tcpSocket->startServer()) {
103
+ promise.Resolve("TCP server started successfully on port " + std::to_string(static_cast<int>(port)));
104
+ } else {
105
+ promise.Reject(React::ReactError{"Error", "Failed to start TCP server"});
106
+ }
107
+
108
+ } catch (const std::exception& e) {
109
+ promise.Reject(React::ReactError{"Error", e.what()});
110
+ }
111
+ }
112
+
113
+ void ReactNativeTcpWindows::closeConnection(React::ReactPromise<std::string> &&promise) noexcept {
114
+ try {
115
+ OutputDebugStringA("Called Close Connection for TCP socket...\n");
116
+ if (m_tcpSocket) {
117
+ OutputDebugStringA("Closing TCP socket...\n");
118
+ m_tcpSocket->close();
119
+ m_tcpSocket.reset();
120
+ promise.Resolve("Connection closed successfully");
121
+ } else {
122
+ OutputDebugStringA("No active TCP socket to close.\n");
123
+ promise.Reject(React::ReactError{ "Error", "No connection open" });
124
+ }
125
+ } catch (const std::exception& e) {
126
+ std::string errorMsg = std::string("Exception in closeConnection: ") + e.what();
127
+ OutputDebugStringA(errorMsg.c_str());
128
+ promise.Reject(React::ReactError{"Exception", errorMsg});
129
+ } catch (...) {
130
+ OutputDebugStringA("Unknown exception in closeConnection\n");
131
+ promise.Reject(React::ReactError{"Exception", "Unknown exception in closeConnection"});
132
+ }
133
+ }
134
+
135
+ void ReactNativeTcpWindows::write(std::vector<double> const& data,
136
+ React::ReactPromise<bool> &&promise) noexcept {
137
+ if (!m_tcpSocket) {
138
+ promise.Reject("No connection open");
139
+ return;
140
+ }
141
+
142
+ std::vector<uint8_t> byteData;
143
+ byteData.reserve(data.size());
144
+ for (const auto& value : data) {
145
+ byteData.push_back(static_cast<uint8_t>(value));
146
+ }
147
+
148
+ promise.Resolve(m_tcpSocket->write(byteData));
149
+ }
150
+
151
+ void ReactNativeTcpWindows::getConnectionStatus(
152
+ React::ReactPromise<bool> &&promise
153
+ ) noexcept {
154
+ bool isConnected = m_tcpSocket ? m_tcpSocket->isConnected() : false;
155
+ promise.Resolve(isConnected);
156
+ }
157
+ void ReactNativeTcpWindows::OnDataReceived(const std::vector<uint8_t>& data) {
158
+ if (m_context) {
159
+ auto eventData = winrt::Microsoft::ReactNative::JSValueObject();
160
+ winrt::Microsoft::ReactNative::JSValueArray jsDataArray;
161
+ for (auto byte : data) {
162
+ jsDataArray.push_back(static_cast<int>(byte));
163
+ }
164
+
165
+ eventData["data"] = std::move(jsDataArray);
166
+
167
+ m_context.EmitJSEvent(L"RCTDeviceEventEmitter", L"TcpSocketDataReceived", eventData);
168
+ }
169
+ }
170
+
171
+ void ReactNativeTcpWindows::OnClientConnected(const std::string& clientAddress) {
172
+ if (m_context) {
173
+ auto eventData = winrt::Microsoft::ReactNative::JSValueObject();
174
+ eventData["clientAddress"] = clientAddress;
175
+
176
+ m_context.EmitJSEvent(L"RCTDeviceEventEmitter", L"TcpSocketClientConnected", eventData);
177
+ }
178
+ }
179
+
180
+ void ReactNativeTcpWindows::OnClientDisconnected(const std::string& clientAddress) {
181
+ if (m_context) {
182
+ auto eventData = winrt::Microsoft::ReactNative::JSValueObject();
183
+ eventData["clientAddress"] = clientAddress;
184
+
185
+ m_context.EmitJSEvent(L"RCTDeviceEventEmitter", L"TcpSocketClientDisconnected", eventData);
186
+ }
187
+ }
188
+
189
+ void ReactNativeTcpWindows::OnConnectionStatusChanged(bool connected, const std::string& message) {
190
+ if (m_context) {
191
+ auto eventData = winrt::Microsoft::ReactNative::JSValueObject();
192
+ eventData["connected"] = connected;
193
+ eventData["message"] = message;
194
+
195
+ m_context.EmitJSEvent(L"RCTDeviceEventEmitter", L"TcpSocketConnectionStatusChanged", eventData);
196
+ }
197
+ }
198
+
199
+ void ReactNativeTcpWindows::addListener(std::string eventType) noexcept {
200
+ // Event listener management - can be implemented if needed
201
+ }
202
+
203
+ void ReactNativeTcpWindows::removeListeners(double count) noexcept {
204
+ // Event listener management - can be implemented if needed
205
+ }
206
+ } // namespace winrt::ReactNativeTcpWindows
@@ -0,0 +1,3 @@
1
+ EXPORTS
2
+ DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE
3
+ DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE
@@ -0,0 +1,83 @@
1
+ #pragma once
2
+
3
+ #include "pch.h"
4
+ #include "resource.h"
5
+ #include "TcpSocket.h"
6
+
7
+ #if __has_include("codegen/NativeReactNativeTcpWindowsDataTypes.g.h")
8
+ #include "codegen/NativeReactNativeTcpWindowsDataTypes.g.h"
9
+ #endif
10
+ #include "codegen/NativeReactNativeTcpWindowsSpec.g.h"
11
+
12
+ #include "NativeModules.h"
13
+
14
+
15
+ namespace winrt::ReactNativeTcpWindows
16
+ {
17
+
18
+ // See https://microsoft.github.io/react-native-windows/docs/native-platform for help writing native modules
19
+
20
+ REACT_MODULE(ReactNativeTcpWindows)
21
+
22
+ struct ReactNativeTcpWindows
23
+ {
24
+ using ModuleSpec = ReactNativeTcpWindowsCodegen::ReactNativeTcpWindowsSpec;
25
+
26
+ REACT_INIT(Initialize)
27
+ void Initialize(React::ReactContext const &reactContext) noexcept;
28
+
29
+ ~ReactNativeTcpWindows(); // Add this to the struct
30
+
31
+ // REACT_SYNC_METHOD(multiply)
32
+ // double multiply(double a, double b) noexcept;
33
+
34
+ REACT_METHOD(connectToServer)
35
+ void connectToServer(std::string address, double port,
36
+ React::ReactPromise<std::string> &&promise) noexcept;
37
+
38
+ REACT_METHOD(startServer)
39
+ void startServer(double port,
40
+ React::ReactPromise<std::string> &&promise) noexcept;
41
+
42
+ REACT_METHOD(closeConnection)
43
+ void closeConnection(React::ReactPromise<std::string> &&promise) noexcept;
44
+
45
+ REACT_METHOD(write)
46
+ void write(std::vector<double> const& data, React::ReactPromise<bool> &&promise) noexcept;
47
+
48
+ // REACT_METHOD(getConnectionStatus)
49
+ // void getConnectionStatus(React::ReactPromise<winrt::Microsoft::ReactNative::JSValueObject> &&promise) noexcept;
50
+
51
+
52
+ REACT_METHOD(getConnectionStatus)
53
+ void getConnectionStatus(React::ReactPromise<bool> &&promise) noexcept;
54
+
55
+ REACT_METHOD(addListener)
56
+ void addListener(std::string eventType) noexcept;
57
+
58
+ REACT_METHOD(removeListeners)
59
+ void removeListeners(double count) noexcept;
60
+
61
+ void OnDataReceived(const std::vector<uint8_t>& data);
62
+ void OnClientConnected(const std::string& clientAddress);
63
+ void OnClientDisconnected(const std::string& clientAddress);
64
+ void OnConnectionStatusChanged(bool connected, const std::string& message);
65
+
66
+ private:
67
+ React::ReactContext m_context;
68
+ std::unique_ptr<TcpSocket> m_tcpSocket;
69
+ };
70
+ // {
71
+ // using ModuleSpec = ReactNativeTcpWindowsCodegen::ReactNativeTcpWindowsSpec;
72
+
73
+ // REACT_INIT(Initialize)
74
+ // void Initialize(React::ReactContext const &reactContext) noexcept;
75
+
76
+ // REACT_SYNC_METHOD(multiply)
77
+ // double multiply(double a, double b) noexcept;
78
+
79
+ // private:
80
+ // React::ReactContext m_context;
81
+ // };
82
+
83
+ } // namespace winrt::ReactNativeTcpWindows