ws.dart 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import 'dart:async';
  2. import 'dart:convert';
  3. import 'package:the_paint/src/generated/client.pbgrpc.dart';
  4. import 'package:flutter_webrtc/flutter_webrtc.dart';
  5. import 'package:web_socket_channel/web_socket_channel.dart';
  6. class WebRTCChannels {
  7. bool _inCalling = false;
  8. RTCPeerConnection? _pc;
  9. RTCDataChannel? _dc;
  10. PaintClient? _grpcClient;
  11. WebRTCChannels();
  12. final Map<String, dynamic> _iceServers = {
  13. 'iceServers': [
  14. {
  15. 'url': 'stun:melvans.com:3478',
  16. 'username': 'b84e4232f84505e3c3967184df374f2cdaa954f1',
  17. 'credential': 'afc39ae0591c132292f73a87f6f3725311fbafa0'
  18. // 'url': 'stun:stun.l.google.com:19302'
  19. },
  20. ]
  21. };
  22. final Map<String, dynamic> _config = {
  23. 'mandatory': {},
  24. 'optional': [
  25. {'DtlsSrtpKeyAgreement': true},
  26. ],
  27. };
  28. final Map<String, dynamic> _constraints = {
  29. 'mandatory': {},
  30. 'optional': [],
  31. };
  32. final _channel = WebSocketChannel.connect(
  33. Uri.parse('ws://localhost:8081/ws'),
  34. );
  35. Future<void> connect(Function callback) async {
  36. print("Connecting WEBSOCKET...");
  37. _pc = await createPeerConnection(
  38. _iceServers,
  39. );
  40. _pc!.onIceCandidate = (candidate) async {
  41. print('pc2: onIceCandidate: ${candidate.candidate}');
  42. await sendCandidate(candidate);
  43. };
  44. _pc!.onDataChannel = (channel) {
  45. RTCDataChannel dc = channel;
  46. print('\nnew channel');
  47. dc.onDataChannelState = (state) {
  48. print('\ndc2: change state: ${state.toString()}');
  49. };
  50. dc.onMessage = (data) {
  51. callback(MonitorReply.fromBuffer(data.binary));
  52. // dc.send(
  53. // RTCDataChannelMessage('(dc2 ==> dc1) Hello from dc2 echo !!!'));
  54. };
  55. };
  56. final rtcData = _channel.stream.map((event) => RTCData.fromBuffer(event));
  57. await for (var msg in rtcData) {
  58. print(msg.event);
  59. switch (msg.event) {
  60. case "offer":
  61. await _pc!
  62. .setRemoteDescription(RTCSessionDescription(msg.data, msg.event));
  63. var answer = await _pc!.createAnswer();
  64. await _pc!.setLocalDescription(answer);
  65. await sendLocalDescription();
  66. break;
  67. default:
  68. print("invalid event");
  69. }
  70. }
  71. }
  72. sendLocalDescription() async {
  73. RTCSessionDescription? answer = await _pc!.getLocalDescription();
  74. if (answer == null) {
  75. return;
  76. }
  77. final encodedData =
  78. RTCData(data: answer.sdp, event: answer.type).writeToBuffer();
  79. _channel.sink.add(encodedData);
  80. }
  81. sendCandidate(RTCIceCandidate candidate) async {
  82. final encodedData =
  83. RTCData(data: jsonEncode(candidate.toMap()), event: "candidate")
  84. .writeToBuffer();
  85. _channel.sink.add(encodedData);
  86. }
  87. }