Skip to content

Commit f33c27c

Browse files
authored
Merge pull request #66 from cloudwebrtc/golang
For golang server.
2 parents a1e547e + b896df8 commit f33c27c

File tree

10 files changed

+101
-75
lines changed

10 files changed

+101
-75
lines changed

lib/main.dart

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import 'package:flutter/material.dart';
2-
import 'src/utils/key_value_store.dart'
3-
if (dart.library.js) 'src/utils/key_value_store_web.dart';
41
import 'dart:core';
2+
3+
import 'package:flutter/material.dart';
4+
import 'package:shared_preferences/shared_preferences.dart';
5+
56
import 'src/basic_sample/basic_sample.dart';
67
import 'src/call_sample/call_sample.dart';
78
import 'src/call_sample/data_channel_sample.dart';
@@ -21,8 +22,9 @@ enum DialogDemoAction {
2122

2223
class _MyAppState extends State<MyApp> {
2324
List<RouteItem> items;
24-
String _serverAddress = '';
25-
KeyValueStore keyValueStore = KeyValueStore();
25+
String _server = '';
26+
SharedPreferences _prefs;
27+
2628
bool _datachannel = false;
2729
@override
2830
initState() {
@@ -60,9 +62,9 @@ class _MyAppState extends State<MyApp> {
6062
}
6163

6264
_initData() async {
63-
await keyValueStore.init();
65+
_prefs = await SharedPreferences.getInstance();
6466
setState(() {
65-
_serverAddress = keyValueStore.getString('server') ?? 'demo.cloudwebrtc.com';
67+
_server = _prefs.getString('server') ?? 'demo.cloudwebrtc.com';
6668
});
6769
}
6870

@@ -74,13 +76,13 @@ class _MyAppState extends State<MyApp> {
7476
// The value passed to Navigator.pop() or null.
7577
if (value != null) {
7678
if (value == DialogDemoAction.connect) {
77-
keyValueStore.setString('server', _serverAddress);
79+
_prefs.setString('server', _server);
7880
Navigator.push(
7981
context,
8082
MaterialPageRoute(
8183
builder: (BuildContext context) => _datachannel
82-
? DataChannelSample(ip: _serverAddress)
83-
: CallSample(ip: _serverAddress)));
84+
? DataChannelSample(ip: _server)
85+
: CallSample(ip: _server)));
8486
}
8587
}
8688
});
@@ -94,11 +96,11 @@ class _MyAppState extends State<MyApp> {
9496
content: TextField(
9597
onChanged: (String text) {
9698
setState(() {
97-
_serverAddress = text;
99+
_server = text;
98100
});
99101
},
100102
decoration: InputDecoration(
101-
hintText: _serverAddress,
103+
hintText: _server,
102104
),
103105
textAlign: TextAlign.center,
104106
),

lib/src/basic_sample/loopback_sample.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ class _MyAppState extends State<LoopBackSample> {
151151
//change for loopback.
152152
description.type = 'answer';
153153
_peerConnection.setRemoteDescription(description);
154+
155+
_localStream.getAudioTracks()[0].setMicrophoneMute(false);
154156
} catch (e) {
155157
print(e.toString());
156158
}

lib/src/call_sample/signaling.dart

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import 'dart:convert';
22
import 'dart:async';
33
import 'package:flutter_webrtc/webrtc.dart';
4+
45
import 'random_string.dart';
56

67
import '../utils/device_info.dart'
78
if (dart.library.js) '../utils/device_info_web.dart';
89
import '../utils/websocket.dart'
910
if (dart.library.js) '../utils/websocket_web.dart';
11+
import '../utils/turn.dart'
12+
if (dart.library.js) '../utils/turn_web.dart';
1013

1114
enum SignalingState {
1215
CallStateNew,
@@ -30,14 +33,17 @@ typedef void DataChannelMessageCallback(
3033
typedef void DataChannelCallback(RTCDataChannel dc);
3134

3235
class Signaling {
36+
JsonEncoder _encoder = new JsonEncoder();
37+
JsonDecoder _decoder = new JsonDecoder();
3338
String _selfId = randomNumeric(6);
3439
SimpleWebSocket _socket;
3540
var _sessionId;
3641
var _host;
37-
var _port = 4443;
42+
var _port = 8086;
3843
var _peerConnections = new Map<String, RTCPeerConnection>();
3944
var _dataChannels = new Map<String, RTCDataChannel>();
4045
var _remoteCandidates = [];
46+
var _turnCredential;
4147

4248
MediaStream _localStream;
4349
List<MediaStream> _remoteStreams;
@@ -220,7 +226,6 @@ class Signaling {
220226
break;
221227
case 'bye':
222228
{
223-
var from = data['from'];
224229
var to = data['to'];
225230
var sessionId = data['session_id'];
226231
print('bye: ' + sessionId);
@@ -259,11 +264,33 @@ class Signaling {
259264
}
260265

261266
void connect() async {
262-
var url = 'wss://$_host:$_port';
267+
var url = 'https://$_host:$_port/ws';
263268
_socket = SimpleWebSocket(url);
264269

265270
print('connect to $url');
266271

272+
if (_turnCredential == null) {
273+
try {
274+
_turnCredential = await getTurnCredential(_host, _port);
275+
/*{
276+
"username": "1584195784:mbzrxpgjys",
277+
"password": "isyl6FF6nqMTB9/ig5MrMRUXqZg",
278+
"ttl": 86400,
279+
"uris": ["turn:127.0.0.1:19302?transport=udp"]
280+
}
281+
*/
282+
_iceServers = {
283+
'iceServers': [
284+
{
285+
'url': _turnCredential['uris'][0],
286+
'username': _turnCredential['username'],
287+
'credential': _turnCredential['password']
288+
},
289+
]
290+
};
291+
} catch (e) {}
292+
}
293+
267294
_socket.onOpen = () {
268295
print('onOpen');
269296
this?.onStateChange(SignalingState.ConnectionOpen);
@@ -321,6 +348,7 @@ class Signaling {
321348
pc.onIceCandidate = (candidate) {
322349
_send('candidate', {
323350
'to': id,
351+
'from': _selfId,
324352
'candidate': {
325353
'sdpMLineIndex': candidate.sdpMlineIndex,
326354
'sdpMid': candidate.sdpMid,
@@ -375,6 +403,7 @@ class Signaling {
375403
pc.setLocalDescription(s);
376404
_send('offer', {
377405
'to': id,
406+
'from': _selfId,
378407
'description': {'sdp': s.sdp, 'type': s.type},
379408
'session_id': this._sessionId,
380409
'media': media,
@@ -391,6 +420,7 @@ class Signaling {
391420
pc.setLocalDescription(s);
392421
_send('answer', {
393422
'to': id,
423+
'from': _selfId,
394424
'description': {'sdp': s.sdp, 'type': s.type},
395425
'session_id': this._sessionId,
396426
});
@@ -400,8 +430,9 @@ class Signaling {
400430
}
401431

402432
_send(event, data) {
403-
data['type'] = event;
404-
JsonEncoder encoder = new JsonEncoder();
405-
_socket.send(encoder.convert(data));
433+
var request = new Map();
434+
request["type"] = event;
435+
request["data"] = data;
436+
_socket.send(_encoder.convert(request));
406437
}
407438
}

lib/src/utils/key_value_store.dart

Lines changed: 0 additions & 16 deletions
This file was deleted.

lib/src/utils/key_value_store_web.dart

Lines changed: 0 additions & 28 deletions
This file was deleted.

lib/src/utils/turn.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import 'dart:convert';
2+
import 'dart:async';
3+
import 'dart:io';
4+
5+
Future<Map> getTurnCredential(String host, int port) async {
6+
HttpClient client = HttpClient(context: SecurityContext());
7+
client.badCertificateCallback =
8+
(X509Certificate cert, String host, int port) {
9+
print('getTurnCredential: Allow self-signed certificate => $host:$port. ');
10+
return true;
11+
};
12+
var url = 'https://$host:$port/api/turn?service=turn&username=flutter-webrtc';
13+
var request = await client.getUrl(Uri.parse(url));
14+
var response = await request.close();
15+
var responseBody = await response.transform(Utf8Decoder()).join();
16+
print('getTurnCredential:response => $responseBody.');
17+
Map data = JsonDecoder().convert(responseBody);
18+
return data;
19+
}

lib/src/utils/turn_web.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import 'dart:convert';
2+
import 'package:http/http.dart' as http;
3+
4+
Future<Map> getTurnCredential(String host, int port) async {
5+
var url = 'https://$host:$port/api/turn?service=turn&username=flutter-webrtc';
6+
final res = await http.get(url);
7+
if (res.statusCode == 200) {
8+
var data = json.decode(res.body);
9+
print('getTurnCredential:response => $data.');
10+
return data;
11+
}
12+
return {};
13+
}

lib/src/utils/websocket.dart

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ class SimpleWebSocket {
1717

1818
connect() async {
1919
try {
20-
_socket = await WebSocket.connect(_url);
21-
//socket = await _connectForSelfSignedCert(_host, _port);
20+
//_socket = await WebSocket.connect(_url);
21+
_socket = await _connectForSelfSignedCert(_url);
2222
this?.onOpen();
2323
_socket.listen((data) {
2424
this?.onMessage(data);
@@ -38,23 +38,22 @@ class SimpleWebSocket {
3838
}
3939

4040
close() {
41-
_socket.close();
41+
if (_socket != null)
42+
_socket.close();
4243
}
4344

44-
Future<WebSocket> _connectForSelfSignedCert(String host, int port) async {
45+
Future<WebSocket> _connectForSelfSignedCert(url) async {
4546
try {
4647
Random r = new Random();
4748
String key = base64.encode(List<int>.generate(8, (_) => r.nextInt(255)));
48-
SecurityContext securityContext = new SecurityContext();
49-
HttpClient client = HttpClient(context: securityContext);
49+
HttpClient client = HttpClient(context: SecurityContext());
5050
client.badCertificateCallback =
5151
(X509Certificate cert, String host, int port) {
52-
print('Allow self-signed certificate => $host:$port. ');
52+
print('SimpleWebSocket: Allow self-signed certificate => $host:$port. ');
5353
return true;
5454
};
5555

56-
HttpClientRequest request = await client.getUrl(
57-
Uri.parse('https://$host:$port/ws')); // form the correct url here
56+
HttpClientRequest request = await client.getUrl(Uri.parse(url)); // form the correct url here
5857
request.headers.add('Connection', 'Upgrade');
5958
request.headers.add('Upgrade', 'websocket');
6059
request.headers.add(

lib/src/utils/websocket_web.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ class SimpleWebSocket {
1111
OnMessageCallback onMessage;
1212
OnCloseCallback onClose;
1313

14-
SimpleWebSocket(this._url);
14+
SimpleWebSocket(this._url) {
15+
_url = _url.replaceAll('https:', 'wss:');
16+
}
1517

1618
connect() async {
1719
try {
@@ -28,7 +30,7 @@ class SimpleWebSocket {
2830
this?.onClose(e.code, e.reason);
2931
});
3032
} catch (e) {
31-
this?.onClose(e.code, e.reason);
33+
this?.onClose(500, e.toString());
3234
}
3335
}
3436

@@ -42,6 +44,6 @@ class SimpleWebSocket {
4244
}
4345

4446
close() {
45-
_socket.close();
47+
if (_socket != null) _socket.close();
4648
}
4749
}

pubspec.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ dependencies:
1919
# The following adds the Cupertino Icons font to your application.
2020
# Use with the CupertinoIcons class for iOS style icons.
2121
cupertino_icons: ^0.1.2
22-
flutter_webrtc: ^0.2.2
22+
flutter_webrtc: ^0.2.6
2323
shared_preferences:
2424
shared_preferences_macos:
25+
shared_preferences_web:
26+
http: ^0.12.0+4
2527

2628
# Required for MediaRecorder example
2729
path_provider:

0 commit comments

Comments
 (0)