真实设备和 Flutter 中的 socket.io 问题
Problem with real device and socket.io in Flutter
我在调试模式下尝试 运行 在物理设备中使用我的应用程序时遇到了这个问题。
当我尝试调试下一个代码时:
class SocketService with ChangeNotifier {
ServerStatus _serverStatus = ServerStatus.Connecting;
SocketService() {
this._initConfig();
}
void _initConfig() async {
IO.Socket socket = IO.io('http://192.168.56.1:3000/', <String, dynamic>{
'transports': ['websocket'],
'autoConnect': true,
});
socket.on('connect', (_) {
print('connect');
});
socket.on('event', (data) => print(data));
socket.on('disconnect', (_) => print('disconnect'));
socket.on('fromServer', (_) => print(_));
}
}
在我的后端我有这个:
文件index.js
const express = require('express');
const path = require('path');
require('dotenv').config();
const app = express();
const server = require('http').createServer(app);
module.exports.io = require('socket.io')(server);
require('./sockets/socket');
const publicPath = path.resolve( __dirname, 'public' );
app.use( express.static( publicPath ) );
server.listen( process.env.PORT, ( err ) => {
if ( err ) throw new Error(err);
console.log('Servidor corriendo en puerto', process.env.PORT );
});
文件socket.js
const { io } = require('../index');
io.on('connection', client => {
console.log('Cliente conectado');
client.on('disconnect', () => {
console.log('Cliente desconectado');
});
client.on('mensaje', ( payload ) => {
console.log('Mensaje', payload);
io.emit( 'mensaje', { admin: 'Nuevo mensaje' } );
});
});
在网络上运行良好并且打印 'disconnect' 和 'connect' 完美,但是当我尝试在我的手机中调试时,没有任何事情发生,我没有从套接字实例中收到任何消息,如果有人知道如何解决这个问题,我将不胜感激。
您可以将您的代码上传到 Heroku server or you can make a ngrok URL 以将套接字与物理设备连接。
我弄清楚是什么问题了,是 AndroidManifest
我解决的方法是使用下一个代码
在 <application>
我添加这一行 android:usesCleartextTraffic="true"
结果是这样的:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.band_names">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:label="band_names"
android:icon="@mipmap/ic_launcher"
android:usesCleartextTraffic="true">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame. -->
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
我在调试模式下尝试 运行 在物理设备中使用我的应用程序时遇到了这个问题。 当我尝试调试下一个代码时:
class SocketService with ChangeNotifier {
ServerStatus _serverStatus = ServerStatus.Connecting;
SocketService() {
this._initConfig();
}
void _initConfig() async {
IO.Socket socket = IO.io('http://192.168.56.1:3000/', <String, dynamic>{
'transports': ['websocket'],
'autoConnect': true,
});
socket.on('connect', (_) {
print('connect');
});
socket.on('event', (data) => print(data));
socket.on('disconnect', (_) => print('disconnect'));
socket.on('fromServer', (_) => print(_));
}
}
在我的后端我有这个:
文件index.js
const express = require('express');
const path = require('path');
require('dotenv').config();
const app = express();
const server = require('http').createServer(app);
module.exports.io = require('socket.io')(server);
require('./sockets/socket');
const publicPath = path.resolve( __dirname, 'public' );
app.use( express.static( publicPath ) );
server.listen( process.env.PORT, ( err ) => {
if ( err ) throw new Error(err);
console.log('Servidor corriendo en puerto', process.env.PORT );
});
文件socket.js
const { io } = require('../index');
io.on('connection', client => {
console.log('Cliente conectado');
client.on('disconnect', () => {
console.log('Cliente desconectado');
});
client.on('mensaje', ( payload ) => {
console.log('Mensaje', payload);
io.emit( 'mensaje', { admin: 'Nuevo mensaje' } );
});
});
在网络上运行良好并且打印 'disconnect' 和 'connect' 完美,但是当我尝试在我的手机中调试时,没有任何事情发生,我没有从套接字实例中收到任何消息,如果有人知道如何解决这个问题,我将不胜感激。
您可以将您的代码上传到 Heroku server or you can make a ngrok URL 以将套接字与物理设备连接。
我弄清楚是什么问题了,是 AndroidManifest 我解决的方法是使用下一个代码
在 <application>
我添加这一行 android:usesCleartextTraffic="true"
结果是这样的:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.band_names">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:label="band_names"
android:icon="@mipmap/ic_launcher"
android:usesCleartextTraffic="true">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame. -->
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>