socket创建失败_flutter使用socket.io构建socket应用

1f7edc4188c924e5cce4156ced554182.png
http:// socket.io 是一个使用websocket进行socket链接的协议包,定义了聊天相关的协议和使用websocket的规范,基于该协议可以很好的构建一个聊天系统,而不需要自己构建聊天室协议,如房间,消息发送指定人等

flutter中可以使用socket_io_client作为http://socket.io的客户端接入方式,socket_io_client是参考http://socket.io的js包来实现的,其中的api和js包的类似,可以方便的接入由http://socket.io接入的服务端应用,包括node,java等实现

  1. 引入socket_io_client包
dependencies:
  flutter:
    sdk: flutter
  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2
  # socket.io包
  socket_io_client: ^0.9.9

2. 调用http://socket.io中的api链接socket服务端

IO.Socket channel;

@override
void initState() {
  super.initState();

  _listenWebSocket();
}

void _listenWebSocket() async {
  // 构建请求头,可以放一些cookie等信息,这里加上了origin,因为服务端有origin校验
  Map<String, dynamic> headers = new Map();
  headers['origin'] = 'http://127.0.0.1:7001';
  // 建立websocket链接
  // 链接的书写规范,schame://host:port/namespace, 这里socket_io_client在处理链接时候会把path和后面的query参数都作为namespace来处理,所以如果我们的namespace是/的话,就直接使用http://host/
  channel = IO.io('http://127.0.0.1:7001/', <String, dynamic>{
    // 请求的path
    'path': '/ws',
    // 构造的header放这里
    'extraHeaders': headers,
    // 查询参数,扔这里
    'query': {
      'EIO': 3,
      'transport': 'websocket'
    },
    // 说明需要升级成websocket链接
    'transports': ['websocket'],
  });

  // 链接建立成功之后,可以发送数据到socket.io的后端了
  channel.on('connect', (_) {
    print('connect');
    // 发送消息和回调函数给socket.io服务端,在服务端可以直接获取到该方法,然后调用
    channel.emitWithAck('exchange', '11111', ack: (data) {
      print('ack $data') ;
      if (data != null) {
        print('from server $data');
      } else {
        print("Null") ;
      }
    });
  });
  // 链接建立失败时调用
  channel.on('error', (data){
    print('error');
    print(data);
  });
  // 链接出错时调用
  channel.on("connect_error", (data) => print('connect_error: '));
  // 链接断开时调用
  channel.on('disconnect', (_) => print('disconnect======'));
  // 链接关闭时调用
  channel.on('close', (_) => print('close===='));
  // 服务端emit一个message的事件时,可以直接监听到
  channel.on('message', (data) {
    print('onmessage');
    print(data);
  });
}

// 关闭websocket链接,避免内存占用
@override
void dispose() {
  super.dispose();

  print('close');
  channel.close();
}

在使用socket_io_client时,主要需要注意的地方是使用io()创建链接时,链接的构建和一些header头,path等参数的编写,如果链接出错,一般会直接close掉链接

如果是namespace写错的话,会提示:

invalid namespace

这些都可以通过检查链接和path是否写对来校验是否能正常建立链接
使用ack的方式,可以直接在当前的发送消息的函数中,相应数据,而不需要服务端通过事件来发送数据回来,这样能保证数据的一致性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值