Skip to content

Commit

Permalink
Merge pull request #66 from cloudwebrtc/golang
Browse files Browse the repository at this point in the history
For golang server.
  • Loading branch information
cloudwebrtc authored Mar 14, 2020
2 parents a1e547e + b896df8 commit f33c27c
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 75 deletions.
26 changes: 14 additions & 12 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import 'package:flutter/material.dart';
import 'src/utils/key_value_store.dart'
if (dart.library.js) 'src/utils/key_value_store_web.dart';
import 'dart:core';

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

import 'src/basic_sample/basic_sample.dart';
import 'src/call_sample/call_sample.dart';
import 'src/call_sample/data_channel_sample.dart';
Expand All @@ -21,8 +22,9 @@ enum DialogDemoAction {

class _MyAppState extends State<MyApp> {
List<RouteItem> items;
String _serverAddress = '';
KeyValueStore keyValueStore = KeyValueStore();
String _server = '';
SharedPreferences _prefs;

bool _datachannel = false;
@override
initState() {
Expand Down Expand Up @@ -60,9 +62,9 @@ class _MyAppState extends State<MyApp> {
}

_initData() async {
await keyValueStore.init();
_prefs = await SharedPreferences.getInstance();
setState(() {
_serverAddress = keyValueStore.getString('server') ?? 'demo.cloudwebrtc.com';
_server = _prefs.getString('server') ?? 'demo.cloudwebrtc.com';
});
}

Expand All @@ -74,13 +76,13 @@ class _MyAppState extends State<MyApp> {
// The value passed to Navigator.pop() or null.
if (value != null) {
if (value == DialogDemoAction.connect) {
keyValueStore.setString('server', _serverAddress);
_prefs.setString('server', _server);
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => _datachannel
? DataChannelSample(ip: _serverAddress)
: CallSample(ip: _serverAddress)));
? DataChannelSample(ip: _server)
: CallSample(ip: _server)));
}
}
});
Expand All @@ -94,11 +96,11 @@ class _MyAppState extends State<MyApp> {
content: TextField(
onChanged: (String text) {
setState(() {
_serverAddress = text;
_server = text;
});
},
decoration: InputDecoration(
hintText: _serverAddress,
hintText: _server,
),
textAlign: TextAlign.center,
),
Expand Down
2 changes: 2 additions & 0 deletions lib/src/basic_sample/loopback_sample.dart
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ class _MyAppState extends State<LoopBackSample> {
//change for loopback.
description.type = 'answer';
_peerConnection.setRemoteDescription(description);

_localStream.getAudioTracks()[0].setMicrophoneMute(false);
} catch (e) {
print(e.toString());
}
Expand Down
43 changes: 37 additions & 6 deletions lib/src/call_sample/signaling.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import 'dart:convert';
import 'dart:async';
import 'package:flutter_webrtc/webrtc.dart';

import 'random_string.dart';

import '../utils/device_info.dart'
if (dart.library.js) '../utils/device_info_web.dart';
import '../utils/websocket.dart'
if (dart.library.js) '../utils/websocket_web.dart';
import '../utils/turn.dart'
if (dart.library.js) '../utils/turn_web.dart';

enum SignalingState {
CallStateNew,
Expand All @@ -30,14 +33,17 @@ typedef void DataChannelMessageCallback(
typedef void DataChannelCallback(RTCDataChannel dc);

class Signaling {
JsonEncoder _encoder = new JsonEncoder();
JsonDecoder _decoder = new JsonDecoder();
String _selfId = randomNumeric(6);
SimpleWebSocket _socket;
var _sessionId;
var _host;
var _port = 4443;
var _port = 8086;
var _peerConnections = new Map<String, RTCPeerConnection>();
var _dataChannels = new Map<String, RTCDataChannel>();
var _remoteCandidates = [];
var _turnCredential;

MediaStream _localStream;
List<MediaStream> _remoteStreams;
Expand Down Expand Up @@ -220,7 +226,6 @@ class Signaling {
break;
case 'bye':
{
var from = data['from'];
var to = data['to'];
var sessionId = data['session_id'];
print('bye: ' + sessionId);
Expand Down Expand Up @@ -259,11 +264,33 @@ class Signaling {
}

void connect() async {
var url = 'wss://$_host:$_port';
var url = 'https://$_host:$_port/ws';
_socket = SimpleWebSocket(url);

print('connect to $url');

if (_turnCredential == null) {
try {
_turnCredential = await getTurnCredential(_host, _port);
/*{
"username": "1584195784:mbzrxpgjys",
"password": "isyl6FF6nqMTB9/ig5MrMRUXqZg",
"ttl": 86400,
"uris": ["turn:127.0.0.1:19302?transport=udp"]
}
*/
_iceServers = {
'iceServers': [
{
'url': _turnCredential['uris'][0],
'username': _turnCredential['username'],
'credential': _turnCredential['password']
},
]
};
} catch (e) {}
}

_socket.onOpen = () {
print('onOpen');
this?.onStateChange(SignalingState.ConnectionOpen);
Expand Down Expand Up @@ -321,6 +348,7 @@ class Signaling {
pc.onIceCandidate = (candidate) {
_send('candidate', {
'to': id,
'from': _selfId,
'candidate': {
'sdpMLineIndex': candidate.sdpMlineIndex,
'sdpMid': candidate.sdpMid,
Expand Down Expand Up @@ -375,6 +403,7 @@ class Signaling {
pc.setLocalDescription(s);
_send('offer', {
'to': id,
'from': _selfId,
'description': {'sdp': s.sdp, 'type': s.type},
'session_id': this._sessionId,
'media': media,
Expand All @@ -391,6 +420,7 @@ class Signaling {
pc.setLocalDescription(s);
_send('answer', {
'to': id,
'from': _selfId,
'description': {'sdp': s.sdp, 'type': s.type},
'session_id': this._sessionId,
});
Expand All @@ -400,8 +430,9 @@ class Signaling {
}

_send(event, data) {
data['type'] = event;
JsonEncoder encoder = new JsonEncoder();
_socket.send(encoder.convert(data));
var request = new Map();
request["type"] = event;
request["data"] = data;
_socket.send(_encoder.convert(request));
}
}
16 changes: 0 additions & 16 deletions lib/src/utils/key_value_store.dart

This file was deleted.

28 changes: 0 additions & 28 deletions lib/src/utils/key_value_store_web.dart

This file was deleted.

19 changes: 19 additions & 0 deletions lib/src/utils/turn.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import 'dart:convert';
import 'dart:async';
import 'dart:io';

Future<Map> getTurnCredential(String host, int port) async {
HttpClient client = HttpClient(context: SecurityContext());
client.badCertificateCallback =
(X509Certificate cert, String host, int port) {
print('getTurnCredential: Allow self-signed certificate => $host:$port. ');
return true;
};
var url = 'https://$host:$port/api/turn?service=turn&username=flutter-webrtc';
var request = await client.getUrl(Uri.parse(url));
var response = await request.close();
var responseBody = await response.transform(Utf8Decoder()).join();
print('getTurnCredential:response => $responseBody.');
Map data = JsonDecoder().convert(responseBody);
return data;
}
13 changes: 13 additions & 0 deletions lib/src/utils/turn_web.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import 'dart:convert';
import 'package:http/http.dart' as http;

Future<Map> getTurnCredential(String host, int port) async {
var url = 'https://$host:$port/api/turn?service=turn&username=flutter-webrtc';
final res = await http.get(url);
if (res.statusCode == 200) {
var data = json.decode(res.body);
print('getTurnCredential:response => $data.');
return data;
}
return {};
}
17 changes: 8 additions & 9 deletions lib/src/utils/websocket.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ class SimpleWebSocket {

connect() async {
try {
_socket = await WebSocket.connect(_url);
//socket = await _connectForSelfSignedCert(_host, _port);
//_socket = await WebSocket.connect(_url);
_socket = await _connectForSelfSignedCert(_url);
this?.onOpen();
_socket.listen((data) {
this?.onMessage(data);
Expand All @@ -38,23 +38,22 @@ class SimpleWebSocket {
}

close() {
_socket.close();
if (_socket != null)
_socket.close();
}

Future<WebSocket> _connectForSelfSignedCert(String host, int port) async {
Future<WebSocket> _connectForSelfSignedCert(url) async {
try {
Random r = new Random();
String key = base64.encode(List<int>.generate(8, (_) => r.nextInt(255)));
SecurityContext securityContext = new SecurityContext();
HttpClient client = HttpClient(context: securityContext);
HttpClient client = HttpClient(context: SecurityContext());
client.badCertificateCallback =
(X509Certificate cert, String host, int port) {
print('Allow self-signed certificate => $host:$port. ');
print('SimpleWebSocket: Allow self-signed certificate => $host:$port. ');
return true;
};

HttpClientRequest request = await client.getUrl(
Uri.parse('https://$host:$port/ws')); // form the correct url here
HttpClientRequest request = await client.getUrl(Uri.parse(url)); // form the correct url here
request.headers.add('Connection', 'Upgrade');
request.headers.add('Upgrade', 'websocket');
request.headers.add(
Expand Down
8 changes: 5 additions & 3 deletions lib/src/utils/websocket_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ class SimpleWebSocket {
OnMessageCallback onMessage;
OnCloseCallback onClose;

SimpleWebSocket(this._url);
SimpleWebSocket(this._url) {
_url = _url.replaceAll('https:', 'wss:');
}

connect() async {
try {
Expand All @@ -28,7 +30,7 @@ class SimpleWebSocket {
this?.onClose(e.code, e.reason);
});
} catch (e) {
this?.onClose(e.code, e.reason);
this?.onClose(500, e.toString());
}
}

Expand All @@ -42,6 +44,6 @@ class SimpleWebSocket {
}

close() {
_socket.close();
if (_socket != null) _socket.close();
}
}
4 changes: 3 additions & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ dependencies:
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
flutter_webrtc: ^0.2.2
flutter_webrtc: ^0.2.6
shared_preferences:
shared_preferences_macos:
shared_preferences_web:
http: ^0.12.0+4

# Required for MediaRecorder example
path_provider:
Expand Down

0 comments on commit f33c27c

Please sign in to comment.