【问题标题】:Socket.io connection not working in Flutter and NodejsSocket.io 连接在 Flutter 和 Nodejs 中不起作用
【发布时间】:2021-11-09 05:44:28
【问题描述】:

请我使用 Flutter 中的 socket_io_client 包来处理 Nodejs 中的套接字 io。 socket.io 在服务器 (Nodejs) 上运行良好,但在客户端 (Flutter) 上无法连接到服务器。下面是我的代码:

服务器代码

const express = require( 'express' ),
    app = express(),
    httpServer = require( 'http' ).createServer( app ),
    io = require( 'socket.io' )( httpServer );
httpServer.listen( 3000, () => console.log( 'Server is running' ) );
let connectedUsers = [];
io.on( 'connection', ( socket ) =>
{
    console.log(socket.id);
    connectedUsers.push( {
        socketId: socket.id,
    } );

    socket.on( 'connectedUsers', ( _ ) =>
    {
        socket.broadcast.emit( 'connectedUsers', connectedUsers );
    } );

    socket.on( "connectedUser", ( data ) =>
    {
        console.log( data );
        const { userId, userName } = data;
    });

    socket.on( 'disconnect', () =>
    {
        const disConnectedUsers = connectedUsers.filter(
            ( user ) => user.socketId !== socket.id
        );
        const leavingUser = connectedUsers.find(
            ( user ) => user.socketId === socket.id
        );
        connectedUsers = disConnectedUsers;
        console.log( connectedUsers );
        connectedUsers.forEach( ( user ) =>
            io.to( user.socketId ).emit( 'leavingUser', leavingUser )
        );
    } );
} );

客户端代码

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:line_icons/line_icons.dart';
import 'package:sharpcall/providers/theme_notifier.dart';
import 'package:sharpcall/views/components/destination_item.dart';
import 'package:sharpcall/views/screens/contact_screen.dart';
import 'package:sharpcall/views/screens/phone_screen.dart';
import 'package:sharpcall/views/screens/favorite_screen.dart';
import 'package:sharpcall/views/screens/setting_screen.dart';
import 'package:socket_io_client/socket_io_client.dart' as client;

final _stateBottomIndex = StateProvider<int>((ref) => 0);

class MainScreen extends StatefulWidget {
  final StateNotifierProvider<ThemeNotifier, bool> themeNotifier;

  const MainScreen({
    Key? key,
    required this.themeNotifier,
  }) : super(key: key);

  @override
  State<MainScreen> createState() => _MainScreenState();
}

class _MainScreenState extends State<MainScreen> {
  final PageController _pageController =
      PageController(initialPage: 0, keepPage: true);

  @override
  void initState() {
    client.Socket socket = client.io('http://192.168.42.51:3000');
    socket.onConnect((data) => socket.emit("connectedUser", {
          "userId": socket.id,
          "userName": "Woo Bear",
        }));

    socket.on("connectedUsers", (data) => print(data));
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Consumer(
      builder: (context, watch, child) {
        final stateBottomIndex = watch(_stateBottomIndex);
        return Scaffold(
          body: SizedBox(
            child: PageView(
              allowImplicitScrolling: true,
              physics: const BouncingScrollPhysics(),
              controller: _pageController,
              onPageChanged: (value) {
                stateBottomIndex.state = value;
              },
              children: [
                const PhoneScreen(),
                const ContactScreen(),
                const FavoriteScreen(),
                SettingScreen(
                  themeNotifier: widget.themeNotifier,
                ),
              ],
            ),
          ),
          bottomNavigationBar: NavigationBarTheme(
            data: NavigationBarThemeData(
              backgroundColor: Theme.of(context).scaffoldBackgroundColor,
              height: kBottomNavigationBarHeight,
              indicatorColor: Colors.transparent,
            ),
            child: NavigationBar(
              selectedIndex: stateBottomIndex.state,
              onDestinationSelected: (value) {
                _pageController.animateToPage(
                  value,
                  duration: const Duration(milliseconds: 200),
                  curve: Curves.easeInOut,
                );
                stateBottomIndex.state = value;
              },
              backgroundColor: Theme.of(context).scaffoldBackgroundColor,
              animationDuration: const Duration(milliseconds: 300),
              destinations: [
                DestinationItem(
                  stateBottomIndex: stateBottomIndex.state,
                  icon: LineIcons.phone,
                  name: "Phone",
                  initialIndex: 0,
                ),
                DestinationItem(
                  stateBottomIndex: stateBottomIndex.state,
                  icon: Icons.perm_contact_calendar_outlined,
                  name: "Contacts",
                  initialIndex: 1,
                ),
                DestinationItem(
                  stateBottomIndex: stateBottomIndex.state,
                  icon: LineIcons.star,
                  name: "Favorites",
                  initialIndex: 2,
                ),
                DestinationItem(
                  stateBottomIndex: stateBottomIndex.state,
                  icon: LineIcons.cogs,
                  name: "Settings",
                  initialIndex: 3,
                ),
              ],
            ),
          ),
          floatingActionButton: stateBottomIndex.state == 2
              ? FloatingActionButton(
                  backgroundColor: Theme.of(context).canvasColor,
                  onPressed: () {},
                  child: Icon(
                    Icons.star_border,
                    color: Theme.of(context).textTheme.headline1!.color,
                  ),
                )
              : null,
        );
      },
    );
  }
}

我正在使用我的远程 IP 地址在我的真实 Android 设备上测试应用程序。请问我错过了什么或需要在服务器上进行配置吗?请帮帮我。

【问题讨论】:

  • 您说它在服务器上运行良好,您是如何测试的?您可以与其他客户联系吗?
  • 是的,它在服务器上运行良好,但客户端无法连接到服务器。我以为是因为 IP 地址的缘故,它不起作用,不是吗?
  • 我正在真正的 Android 设备上测试应用程序,这就是我使用 IP 地址的原因。
  • 如果无法连接到服务器,如何知道服务器是否运行良好?我的问题又是:你是否以任何其他方式连接到服务器,所以你的句子“它在服务器上运行良好”得到了经验测试的支持,而不仅仅是信仰?
  • 好的。我运行服务器 - nodejs 并且客户端(浏览器)确实在本地连接到服务器。然后我使用了socket_io_client包连接到服务器,但是还是不行。

标签: node.js flutter dart socket.io


【解决方案1】:

如果您在本地服务器上运行,则需要反向代理来连接到您的服务器。如果您的 android 设备通过 USB 连接,请尝试在终端中运行 adb reverse tcp:3000 tcp:3000,您将能够连接到本地 nodejs 服务器

【讨论】:

  • 好的。试过了,还是连接不上。 ?
  • 通过将 Nodejs 的 Socket.io 版本降级到 2.4.1 解决了这个问题。它适用于真正的 Android 设备和模拟器。感谢您的帮助。
  • 啊,以前是我的问题?,我试过了。很高兴你解决了!
  • @LeslieJoe,我需要你的帮助,我也遇到了同样的问题,你的 socket_io_client 版本是什么?
  • @Zionnite,你可以使用最新的socket_io_client。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-05
  • 2017-08-09
  • 1970-01-01
  • 2016-07-01
  • 1970-01-01
  • 2022-01-13
  • 2020-10-05
相关资源
最近更新 更多