flutter - 我在 Flutter 中的应用集成了与 Socket.io 的聊天,并且不连接到远程服务器
问题描述
开发一个包含使用 Socket.io 的聊天的 Flutter 应用程序
该服务器由 AWS 上的 EC2 实例托管。我首先在本地计算机上进行了测试。
使用 socket.io 和 Web 客户端创建一个服务器来测试连接,它工作正常。
服务器代码:
const path = require("path");
const http = require('http');
const express = require("express");
const socketio = require("socket.io");
const app = express();
app.set('port', 3000);
//static files
app.use(express.static(path.join(__dirname, "public")));
//start the server
const server = app.listen(app.get('port'), () => {
console.log("server on port", app.get('port'));
});
const server2 = http.createServer(server);
const io = socketio(server);
//websockects
io.on('connection', (socket) => {
console.log("new connection " + socket.id);
console.log(socket);
socket.on('chat:message', (data) => {
console.log(data.constructor.name);
console.log(data);
io.sockets.emit("chat:server", data);
});
socket.on('chat:typing', (data) => {
console.log(data);
socket.broadcast.emit("chat:typing", data);
});
socket.on('message', (data) => {
console.log(data.constructor.name);
console.log(data);
io.sockets.emit("news", { respuesta: "Recibio" });
});
});
客户端代码:
///coneccion al servidor
const socket = io();
//dom elements
let message = document.getElementById("message");
let username = document.getElementById("username");
let btn = document.getElementById("button");
let output = document.getElementById("output");
let actions = document.getElementById("actions");
//evento de envio de mensaje
btn.addEventListener('click', function() {
console.log({
username: username.value,
message: message.value
});
//socket que emite el mensaje al servidor
socket.emit("chat:message", {
username: username.value,
message: message.value
});
});
//Escuchador de teclado, se activa cuando el usuario teclea
message.addEventListener('keypress', function() {
//emite el nombre del usuario cuando este esta teclando al lado del cliente
socket.emit("chat:typing", username.value);
socket.emit("message", username.value);
});
//socket que recibe los mensajes del servidor
socket.on("chat:server", function(data) {
console.log(data);
actions.innerHTML = "";
output.innerHTML += "<p><strong>" + data.username + "</strong>: " + data.message + " </p>";
});
//socket que recibe el nombre del usuario que esta teclando
socket.on("chat:typing", function(data) {
console.log(data);
actions.innerHTML = "<p><strong>" + data + "</strong> esta escribiendo </p>";
});
socket.on("news", function(data) {
console.log(data);
});
之后,我将服务器代码上传到 EC2 实例。服务器使用 NGINX,我必须对其进行修改,以便它接受来自服务器外部的连接,如下所示:
Access-Control-Allow-Origin: *
我只是修改了客户端的连接套接字:
const socket = io("https://mycustomdomain.org");
并且工作,从我的电脑连接到服务器。现在我的问题是颤振。我尝试了两个库:
-https://pub.dev/packages/socket_io_client -https://pub.dev/packages/adhara_socket_io
使用这两个库中的任何一个,我都无法连接到服务器。在 localhost 中它可以工作,但是当我尝试连接到 EC2 服务器时,我无法连接。
我做了每个库的简单例子,
与阿达拉:
Future<void> socketConfig() async {
SocketIOManager manager = SocketIOManager();
SocketIO socket = await manager.createInstance('https://mycustomdomain.org'); //TODO change the port accordingly
socket.onConnect((data){
print("connected...");
print(data);
socket.emit("message", ["Hello world!"]);
});
socket.on("news", (data){ //sample event
print("news");
print(data);
});
socket.connect();
///disconnect using
///manager.
}
socketConfig();
并使用 socket.io-client
import 'package:socket_io/socket_io.dart';
import 'package:socket_io_client/socket_io_client.dart' as IO;
main() {
// Dart server
var io = new Server();
var nsp = io.of('/some');
nsp.on('connection', (Socket client) {
print('connection /some');
client.on('msg', (data) {
print('data from /some => $data');
client.emit('fromServer', "ok 2");
});
});
io.on('connection', (Socket client) {
print('connection default namespace');
client.on('msg', (data) {
print('data from default => $data');
client.emit('fromServer', "ok");
});
});
io.listen(3000);
// Dart client
IO.Socket socket = IO.io('https://mycustomdomain.org/');
socket.onConnect((_) {
print('connect');
socket.emit('msg', 'test');
});
socket.on('event', (data) => print(data));
socket.onDisconnect((_) => print('disconnect'));
socket.on('fromServer', (_) => print(_));
}
它甚至无法检测到它们连接到服务器。顺便说一句,我的域有 SSL 证书。
知道会发生什么吗?
解决方案
我的node.js项目使用的是socket.io 3.0.0版(最新的),但是我的flutter客户端好像不支持,所以尝试降级到2.3.0版(不要手动做,在换句话说不要手动修改文件)
npm uninstall socket.io
npm install socket.io@2.3.0
和
由于某种原因,“自动连接”不起作用,因此请尝试手动连接。
IO.Socket socket = IO.io('https://mycustomdomain.org', <String, dynamic>{
'transports': ['websocket'],
'autoConnect': false,
});
// Dart client
socket.on('connect', (_) {
print('connect');
});
socket.on('event', (data) => print(data));
socket.on('disconnect', (_) => print('disconnect'));
socket.on('fromServer', (_) => print(_));
// add this line
socket.connect();
推荐阅读
- r - 禁用特定标签面板的侧边栏
- python - 在使用 mrjob 的 MapReduce 作业中使用 SORT_VALUES 时出现问题(键值在减速器输入中未排序)
- javascript - 如何在 netlify 中使用带有 express 的 ejs 视图引擎?
- machine-learning - 逻辑回归在简单示例中不起作用
- python - 迭代 python 3.5.6 和 3.7.3 之间的 pandas 数据帧差异
- postgresql - 将每个月插入自己的列(postgresql)
- android - 错误:无法解决:sqlite 受影响的模块:app
- r - SplitSeries 在 r 中的 Packed Bubble Highchart 中不起作用
- java - 什么时候需要使用实现 Iterable
- sql - 如何在 SQL 中对层次结构中的组织结构进行编码