基于web_socket_channel 实现弹幕通信

文章将介绍如何对web_socket_channel进行通用封装

引入插件

pubspec.yaml

web_socket_channel: ^1.2.0

插件封装

hi_socket.dart

封装思想:针对 websocket 插件提供的功能,进行抽象层的提取封装,从建立连接、和服务端通信(发送、接收)、以及通信中的异常处理、还有关闭连接等功能

class HiSocket extends ISocket {
  final Map<String, dynamic> headers;

  static const _URL = "wss://api.devio.org/uapi/fa/barrage/";

  ValueChanged<List<BarrageModel>> _callBack;

  IOWebSocketChannel _channel;

  /// 心跳间隔秒数,根据服务器实际timeout时间来调整,这里Nginx服务器的timeout为60
  int _intervalSeconds = 50;

  HiSocket(this.headers);

  /// 关闭连接
  @override
  void close() {
    _channel?.sink?.close();
  }

  /// 监听服务端返回的数据
  @override
  ISocket listen(ValueChanged<List<BarrageModel>> _callBack) {
    _callBack = _callBack;
    return this;
  }

  /// 建立连接
  @override
  ISocket open(String vid) {
    _channel = IOWebSocketChannel.connect(_URL + vid,
        headers: headers, pingInterval: Duration(seconds: _intervalSeconds));
    _channel.stream.handleError((error) {
      print('连接发生错误:$error');
    }).listen((message) {
      // 监听服务端返回的消息
      _handleMessage(message);
    });
    return this;
  }

  /// 向服务端发送消息
  @override
  ISocket send(String message) {
    _channel?.sink?.add(message);
    return this;
  }

  /// 处理从服务端返回的消息
  void _handleMessage(message) {
    var result = BarrageModel.fromJson(message);
    if (result != null && _callBack != null) {
      _callBack(message);
    }
  }
}
/// 抽象层封装:提取通用socket 功能
abstract class ISocket {
  /// 建立连接
  /// vid: 视频ID,返回 ISocket 是为了链式调用
  ISocket open(String vid);

  /// 发送弹幕
  ISocket send(String message);

  /// 接收数据
  ISocket listen(ValueChanged<List<BarrageModel>> _callBack);

  /// 关闭连接
  void close();
}

如何使用

	HiSocket _hiSocket;
	@override
	void initState() {
	    super.initState();
	    _initSocket();
	}
	@override
	void dispose() {
	 // 关闭socket
	  _hiSocket.close();
	  super.dispose();
	}
	/// 初始化HiSocket
	void _initSocket() {
	    _hiSocket = HiSocket(HiConstants.headers());
	    // 监听从服务端返回的消息
	    _hiSocket.open(videoModel.vid).listen((value) {
	      print('收到:$value');
	    });
	  }
	}    

hi_constants.dart

和服务端通信鉴权的信息,一般都封装到每一次http请求的 header 中

class HiConstants {
  static String authTokenK = "auth-token";
  static String authTokenV = "ZmEtMjAyMS0wNC0xMiAyMToyMjoyMC1mYQ==fa";

  static String courseFlagK = "course-flag";
  static String courseFlagV = "fa";

  static const theme = "hi_theme";

  /// 设置请求头校验,注意留意:Console的log输出:flutter: received:
  static headers() {
    Map<String, dynamic> header = {
      HiConstants.authTokenK: HiConstants.authTokenV,
      HiConstants.courseFlagK: HiConstants.courseFlagV
    };
    var boardingPass = LoginDao.getBoardingPass();
    if (boardingPass != null) {
      header[LoginDao.BOARDING_PASS] = boardingPass;
    }
    return header;
  }
}

扩展阅读

https://flutterchina.club/cookbook/networking/web-sockets/

https://github.com/wkiwi/flutter_WeChat

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值