Клиент Socket.io для Swift не может подключиться к серверу node.js ⇐ IOS
Клиент Socket.io для Swift не может подключиться к серверу node.js
Я пытаюсь использовать последнюю версию пакета Swift socket.io-client-swift для подключения к моему серверу Socket.io, встроенному в Node.js, но соединение, похоже, не устанавливается, поскольку в файле ничего не регистрируется. консоль, указывающая, что соединение было успешно установлено - ни опроса, ни установления связи.
Вот журналы, которые появляются в приложении и указывают на то, что соединение не может быть установлено:
LOG SocketIOClient{/}: добавление обработчика события: подключение LOG SocketIOClient{/}: добавление обработчика события: отключение. LOG SocketIOClient{/}: добавление обработчика события: ошибка. LOG SocketIOClient{/}: обработка события: statusChange с данными: [connecting, 2] LOG SocketIOClient{/}: присоединение к пространству имен / ЖУРНАЛ SocketManager: попыталась подключить сокет, когда движок не открыт. Подключение LOG SocketManager: добавление движка ЖУРНАЛ SocketEngine: Запуск двигателя. Сервер: https://ws.my-socket-server.com LOG SocketEngine: Подтверждение связи LOG SocketManager: диспетчер выпускается LOG SocketIOClient{/}: добавление обработчика события: подключение. LOG SocketIOClient{/}: добавление обработчика события: отключение. LOG SocketIOClient{/}: добавление обработчика события: ошибка. LOG SocketIOClient{/}: обработка события: statusChange с данными: [connecting, 2] LOG SocketIOClient{/}: присоединение к пространству имен / ЖУРНАЛ SocketManager: попыталась подключить сокет, когда движок не открыт. Подключение LOG SocketManager: попробовал подключить уже активный сокет. Как вы можете видеть, он говорит: «Пыталась подключить сокет, когда движок не открыт» и очень рано отпускает Менеджер.
Вот мой одноэлементный WebSocketManager, который я создаю, чтобы использовать сокет для всех моих представлений:
импортировать фундамент импортировать SocketIO класс WebSocketManager: NSObject, ObservableObject, URLSessionWebSocketDelegate { статический пусть общий = WebSocketManager() @Published var DrawingSocket: SocketIOClient? частный вар DrawingSocketManager: SocketManager? частный let DrawingSocketURL = URL (строка: «https://ws.my-socket-server.com»)! переопределить частную инициализацию() { супер.инит() настройкаDrawingSocket() } частная функция setupDrawingSocket() { DrawingSocketManager = SocketManager(socketURL: DrawingSocketURL, config: [.log(true), .reconnectAttempts(5), .reconnectWaitMax(5), .forceWebsockets(true)]) DrawingSocket = DrawingSocketManager?.defaultSocket DrawingSocket?.on(clientEvent: .connect) { _, _ в print("Сокет чертежа подключен") } DrawingSocket?.on(clientEvent: .disconnect) {данные, _ в print("Сокет чертежа отключен: \(data)") } DrawingSocket?.on(clientEvent:.error) {данные, _ в print("Ошибка сокета чертежа: \(data)") } если DrawingSocket?.status != .connected { DrawingSocket?.connect() } } func sendDrawingMessage (_ действие: строка, данные: любой) { Guard пусть DrawingSocket = DrawingSocket еще { print("Сокет для рисования недоступен") возвращаться } // Проверяем, подключен ли сокет перед отправкой сообщения если DrawingSocket.status == .connected { DrawingSocket.emit (действие, данные как! SocketData) } еще { print("Сокет для рисования не подключен. Не могу отправить сообщение.") } } вар isDrawingSocketConnected: Bool { вернуть DrawingSocket?.status == .connected } } Вот точка входа ко всем моим представлениям:
импортировать SwiftUI @основной структура my_iosApp: Приложение { var body: некоторая сцена { ОкноГруппа { Дом() .environmentObject(WebSocketManager.shared) .environmentObject(GlobalStateManager.shared) } } } и, наконец, вот где я использую сокет для отправки сообщения на сервер:
импортировать SocketIO импортировать SwiftUI структура GameCodeDisplay: Посмотреть { @EnvironmentObject var globalStateManager: GlobalStateManager @EnvironmentObject var webSocketManager: WebSocketManager пусть gameCode: String var onCancel: () -> Пустота частная переменная DrawingSocket: SocketIOClient init(gameCode: String, onCancel: @escaping () -> Void) { self.gameCode = код игры self.onCancel = onCancel let менеджер = SocketManager(socketURL: URL(строка: "https://ws.my-socket-server.com")!, config: [.log(true), .reconnectAttempts(5), .reconnectWaitMax(5), .forceWebsockets(истина)]) self.drawingSocket = менеджер.defaultSocket } var body: some View { ZStack { Цвет (красный: 115,0/255,0, зеленый: 5,0/255,0, синий: 60,0/255,0) .edgesIgnoringSafeArea(.all) ВСтек { Spacer() // Перемещает содержимое в центр Text("Ваш код игры:") .font(.title) .fontWeight(.bold) .foregroundColor(.white) Текст (код игры) .font(.largeTitle) .fontWeight(.bold) .foregroundColor(.white) .padding(.дно) ПрокруткаView { ВСтек { ForEach(globalStateManager.players, id: \.self) { игрок в Текст (плеер) .frame(maxWidth: .infinity) .multilineTextAlignment(.center) .foregroundColor(.white) } } } .frame(maxHeight: 200) // Отрегулируйте по мере необходимости если globalStateManager.players.count >= 5 { Кнопка("Начать!") { startGame(drawingSocket: DrawingSocket, gameCode: gameCode) } .disabled(globalStateManager.players.count < 5) .padding() .foregroundColor(.green) } Кнопка("Отмена") { onCancel() LeaveGame (webSocketManager: webSocketManager, globalStateManager: globalStateManager) } .padding() .foregroundColor(.желтый) Spacer() // Позволяет кнопке находиться внизу } .frame(maxWidth: .infinity, maxHeight: .infinity) .padding() // Добавляем отступы вокруг всего VStack }.onAppear { настройкаDrawingSocketEvents() } } частная функция setupDrawingSocketEvents() { Guard let DrawingSocket = webSocketManager.drawingSocket еще { print("Сокет для рисования недоступен") возвращаться } DrawingSocket.on(clientEvent: .connect) { _, _ в print("Сокет чертежа подключен") // Дополнительный код для подключения сокета } DrawingSocket.on(clientEvent:.disconnect) {данные, _ в print("Сокет чертежа отключен: \(data)") // Дополнительный код, когда сокет отключается } DrawingSocket.on(clientEvent:.error) {данные, _ в print("Ошибка сокета чертежа: \(data)") // Дополнительная обработка ошибок } // Подключаемся к сокету, если не подключено если !webSocketManager.isDrawingSocketConnected { рисунокSocket.connect() } } частная функция startGame (drawingSocket: SocketIOClient, gameCode: String) { print("GameCodeDisplay: Запуск игры с gameCode - \(gameCode)") webSocketManager.sendDrawingMessage("joinGame", данные: gameCode) webSocketManager.sendDrawingMessage("startGame", данные: gameCode) } частная функция LeaveGame (webSocketManager: WebSocketManager, globalStateManager: GlobalStateManager) { print("GameCodeDisplay: Выход из игры с кодом игры - \(gameCode)") webSocketManager.sendLeaveGameMessage(gameCode: gameCode, имя пользователя: globalStateManager.username) вебSocketManager.disconnect() globalStateManager.players.removeAll() globalStateManager.setUsername(usernameToSet: "") } } Вот сервер Node.js, на котором работает сокет. Я использую версию socket.io: "^4.7.2":
const express = require("express"); const {Сервер} = require("socket.io"); const cors = require("cors"); const http = require("http"); const разрешеноOrigins = [ "https://сайт-1.com", "https://сайт-2.com", "http://локальный хост:3000", ]; константное приложение = экспресс(); приложение.use( корс({ происхождение: функция (происхождение, обратный вызов) { console.log("происхождение: ", происхождение); if (!origin) возвращает обратный вызов (null, true); // Разрешить запросы без источника (например, мобильные приложения или запросы на завивку) if (allowedOrigins.indexOf(origin) === -1) { константное сообщение = «Политика CORS для этого сайта не разрешает доступ из указанного источника.»; возврат обратного вызова (новая ошибка (сообщение), ложь); } возврат обратного вызова (ноль, правда); }, }) ); app.get("/health-check", (req, res) => res.status(200).send("OK")); константный сервер = http.createServer(приложение); const io = новый сервер(сервер, { транспорты: ["websocket"], корс: { происхождение: функция (происхождение, обратный вызов) { if (allowedOrigins.indexOf(origin) !== -1) { обратный вызов (ноль, правда); } еще { обратный вызов (новая ошибка («CORS не разрешен»); } }, методы: ["GET", "POST"], }, }); const linkedSockets = новый Set(); io.on("соединение", (сокет) => { ConnectedSockets.add(сокет); socket.on("joinGame", (gameCode, обратный вызов) => { сокет.join(gameCode); console.log(`Сокет с идентификатором ${socket.id} присоединился к комнате: ${gameCode}`); if (обратный вызов typeof === "функция") { callback(`Присоединенная комната: ${gameCode}`); } }); socket.on("startGame", (gameCode) => { console.log("Отправка gameStarted в комнату:", gameCode); io.to(gameCode).emit("gameStarted"); }); }); server.listen(3001, (ошибка) => { linkedSockets.forEach((сокет) => { сокет.disconnect(истина); }); ConnectedSockets.clear(); если (ошибка) выбросить ошибку; console.log("> Готово на http://localhost:3001"); }); Я пробовал разные способы создания упомянутого мной синглтона о WebSocketManager, но безрезультатно. На данный момент я открыт для любых других альтернатив пакета Swift для подключения к моему серверу Socket.io из моего приложения SwiftUI для iOS.
Я пытаюсь использовать последнюю версию пакета Swift socket.io-client-swift для подключения к моему серверу Socket.io, встроенному в Node.js, но соединение, похоже, не устанавливается, поскольку в файле ничего не регистрируется. консоль, указывающая, что соединение было успешно установлено - ни опроса, ни установления связи.
Вот журналы, которые появляются в приложении и указывают на то, что соединение не может быть установлено:
LOG SocketIOClient{/}: добавление обработчика события: подключение LOG SocketIOClient{/}: добавление обработчика события: отключение. LOG SocketIOClient{/}: добавление обработчика события: ошибка. LOG SocketIOClient{/}: обработка события: statusChange с данными: [connecting, 2] LOG SocketIOClient{/}: присоединение к пространству имен / ЖУРНАЛ SocketManager: попыталась подключить сокет, когда движок не открыт. Подключение LOG SocketManager: добавление движка ЖУРНАЛ SocketEngine: Запуск двигателя. Сервер: https://ws.my-socket-server.com LOG SocketEngine: Подтверждение связи LOG SocketManager: диспетчер выпускается LOG SocketIOClient{/}: добавление обработчика события: подключение. LOG SocketIOClient{/}: добавление обработчика события: отключение. LOG SocketIOClient{/}: добавление обработчика события: ошибка. LOG SocketIOClient{/}: обработка события: statusChange с данными: [connecting, 2] LOG SocketIOClient{/}: присоединение к пространству имен / ЖУРНАЛ SocketManager: попыталась подключить сокет, когда движок не открыт. Подключение LOG SocketManager: попробовал подключить уже активный сокет. Как вы можете видеть, он говорит: «Пыталась подключить сокет, когда движок не открыт» и очень рано отпускает Менеджер.
Вот мой одноэлементный WebSocketManager, который я создаю, чтобы использовать сокет для всех моих представлений:
импортировать фундамент импортировать SocketIO класс WebSocketManager: NSObject, ObservableObject, URLSessionWebSocketDelegate { статический пусть общий = WebSocketManager() @Published var DrawingSocket: SocketIOClient? частный вар DrawingSocketManager: SocketManager? частный let DrawingSocketURL = URL (строка: «https://ws.my-socket-server.com»)! переопределить частную инициализацию() { супер.инит() настройкаDrawingSocket() } частная функция setupDrawingSocket() { DrawingSocketManager = SocketManager(socketURL: DrawingSocketURL, config: [.log(true), .reconnectAttempts(5), .reconnectWaitMax(5), .forceWebsockets(true)]) DrawingSocket = DrawingSocketManager?.defaultSocket DrawingSocket?.on(clientEvent: .connect) { _, _ в print("Сокет чертежа подключен") } DrawingSocket?.on(clientEvent: .disconnect) {данные, _ в print("Сокет чертежа отключен: \(data)") } DrawingSocket?.on(clientEvent:.error) {данные, _ в print("Ошибка сокета чертежа: \(data)") } если DrawingSocket?.status != .connected { DrawingSocket?.connect() } } func sendDrawingMessage (_ действие: строка, данные: любой) { Guard пусть DrawingSocket = DrawingSocket еще { print("Сокет для рисования недоступен") возвращаться } // Проверяем, подключен ли сокет перед отправкой сообщения если DrawingSocket.status == .connected { DrawingSocket.emit (действие, данные как! SocketData) } еще { print("Сокет для рисования не подключен. Не могу отправить сообщение.") } } вар isDrawingSocketConnected: Bool { вернуть DrawingSocket?.status == .connected } } Вот точка входа ко всем моим представлениям:
импортировать SwiftUI @основной структура my_iosApp: Приложение { var body: некоторая сцена { ОкноГруппа { Дом() .environmentObject(WebSocketManager.shared) .environmentObject(GlobalStateManager.shared) } } } и, наконец, вот где я использую сокет для отправки сообщения на сервер:
импортировать SocketIO импортировать SwiftUI структура GameCodeDisplay: Посмотреть { @EnvironmentObject var globalStateManager: GlobalStateManager @EnvironmentObject var webSocketManager: WebSocketManager пусть gameCode: String var onCancel: () -> Пустота частная переменная DrawingSocket: SocketIOClient init(gameCode: String, onCancel: @escaping () -> Void) { self.gameCode = код игры self.onCancel = onCancel let менеджер = SocketManager(socketURL: URL(строка: "https://ws.my-socket-server.com")!, config: [.log(true), .reconnectAttempts(5), .reconnectWaitMax(5), .forceWebsockets(истина)]) self.drawingSocket = менеджер.defaultSocket } var body: some View { ZStack { Цвет (красный: 115,0/255,0, зеленый: 5,0/255,0, синий: 60,0/255,0) .edgesIgnoringSafeArea(.all) ВСтек { Spacer() // Перемещает содержимое в центр Text("Ваш код игры:") .font(.title) .fontWeight(.bold) .foregroundColor(.white) Текст (код игры) .font(.largeTitle) .fontWeight(.bold) .foregroundColor(.white) .padding(.дно) ПрокруткаView { ВСтек { ForEach(globalStateManager.players, id: \.self) { игрок в Текст (плеер) .frame(maxWidth: .infinity) .multilineTextAlignment(.center) .foregroundColor(.white) } } } .frame(maxHeight: 200) // Отрегулируйте по мере необходимости если globalStateManager.players.count >= 5 { Кнопка("Начать!") { startGame(drawingSocket: DrawingSocket, gameCode: gameCode) } .disabled(globalStateManager.players.count < 5) .padding() .foregroundColor(.green) } Кнопка("Отмена") { onCancel() LeaveGame (webSocketManager: webSocketManager, globalStateManager: globalStateManager) } .padding() .foregroundColor(.желтый) Spacer() // Позволяет кнопке находиться внизу } .frame(maxWidth: .infinity, maxHeight: .infinity) .padding() // Добавляем отступы вокруг всего VStack }.onAppear { настройкаDrawingSocketEvents() } } частная функция setupDrawingSocketEvents() { Guard let DrawingSocket = webSocketManager.drawingSocket еще { print("Сокет для рисования недоступен") возвращаться } DrawingSocket.on(clientEvent: .connect) { _, _ в print("Сокет чертежа подключен") // Дополнительный код для подключения сокета } DrawingSocket.on(clientEvent:.disconnect) {данные, _ в print("Сокет чертежа отключен: \(data)") // Дополнительный код, когда сокет отключается } DrawingSocket.on(clientEvent:.error) {данные, _ в print("Ошибка сокета чертежа: \(data)") // Дополнительная обработка ошибок } // Подключаемся к сокету, если не подключено если !webSocketManager.isDrawingSocketConnected { рисунокSocket.connect() } } частная функция startGame (drawingSocket: SocketIOClient, gameCode: String) { print("GameCodeDisplay: Запуск игры с gameCode - \(gameCode)") webSocketManager.sendDrawingMessage("joinGame", данные: gameCode) webSocketManager.sendDrawingMessage("startGame", данные: gameCode) } частная функция LeaveGame (webSocketManager: WebSocketManager, globalStateManager: GlobalStateManager) { print("GameCodeDisplay: Выход из игры с кодом игры - \(gameCode)") webSocketManager.sendLeaveGameMessage(gameCode: gameCode, имя пользователя: globalStateManager.username) вебSocketManager.disconnect() globalStateManager.players.removeAll() globalStateManager.setUsername(usernameToSet: "") } } Вот сервер Node.js, на котором работает сокет. Я использую версию socket.io: "^4.7.2":
const express = require("express"); const {Сервер} = require("socket.io"); const cors = require("cors"); const http = require("http"); const разрешеноOrigins = [ "https://сайт-1.com", "https://сайт-2.com", "http://локальный хост:3000", ]; константное приложение = экспресс(); приложение.use( корс({ происхождение: функция (происхождение, обратный вызов) { console.log("происхождение: ", происхождение); if (!origin) возвращает обратный вызов (null, true); // Разрешить запросы без источника (например, мобильные приложения или запросы на завивку) if (allowedOrigins.indexOf(origin) === -1) { константное сообщение = «Политика CORS для этого сайта не разрешает доступ из указанного источника.»; возврат обратного вызова (новая ошибка (сообщение), ложь); } возврат обратного вызова (ноль, правда); }, }) ); app.get("/health-check", (req, res) => res.status(200).send("OK")); константный сервер = http.createServer(приложение); const io = новый сервер(сервер, { транспорты: ["websocket"], корс: { происхождение: функция (происхождение, обратный вызов) { if (allowedOrigins.indexOf(origin) !== -1) { обратный вызов (ноль, правда); } еще { обратный вызов (новая ошибка («CORS не разрешен»); } }, методы: ["GET", "POST"], }, }); const linkedSockets = новый Set(); io.on("соединение", (сокет) => { ConnectedSockets.add(сокет); socket.on("joinGame", (gameCode, обратный вызов) => { сокет.join(gameCode); console.log(`Сокет с идентификатором ${socket.id} присоединился к комнате: ${gameCode}`); if (обратный вызов typeof === "функция") { callback(`Присоединенная комната: ${gameCode}`); } }); socket.on("startGame", (gameCode) => { console.log("Отправка gameStarted в комнату:", gameCode); io.to(gameCode).emit("gameStarted"); }); }); server.listen(3001, (ошибка) => { linkedSockets.forEach((сокет) => { сокет.disconnect(истина); }); ConnectedSockets.clear(); если (ошибка) выбросить ошибку; console.log("> Готово на http://localhost:3001"); }); Я пробовал разные способы создания упомянутого мной синглтона о WebSocketManager, но безрезультатно. На данный момент я открыт для любых других альтернатив пакета Swift для подключения к моему серверу Socket.io из моего приложения SwiftUI для iOS.
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Сервер Node.js Socket IO отключает клиент Python Socket.io через 30 секунд
Anonymous » » в форуме Python - 0 Ответы
- 61 Просмотры
-
Последнее сообщение Anonymous
-