Anuj-Panthri commited on
Commit
7c7b2d5
·
1 Parent(s): 6f0e7f2

added reconnecting to server ability and showing messages in snackbar

Browse files
client/lib/HomeScreen.dart CHANGED
@@ -7,6 +7,8 @@ import 'package:shared_preferences/shared_preferences.dart';
7
  import 'package:web_socket_channel/web_socket_channel.dart';
8
  import 'package:web_socket_channel/status.dart' as status;
9
 
 
 
10
  import 'package:flutter_colorpicker/flutter_colorpicker.dart';
11
 
12
  import 'package:flutter/foundation.dart' show kIsWeb; // to check of platform is web
@@ -36,7 +38,7 @@ class HomeScreen extends StatefulWidget{
36
  }
37
 
38
  class HomeScreenState extends State<HomeScreen>{
39
- late WebSocketChannel channel;
40
  late double width,height;
41
  late SharedPreferences prefs;
42
  double containerHeight = 0,containerWidth=0;
@@ -70,10 +72,6 @@ class HomeScreenState extends State<HomeScreen>{
70
 
71
  // roomidList=["1","2"];
72
  // roomnameList=["room 1","room 2"];
73
- getPreferences();
74
- // setPreferences();
75
- connectWebsocket();
76
- setUsername();
77
 
78
  Map data={
79
  "user": {
@@ -91,6 +89,13 @@ class HomeScreenState extends State<HomeScreen>{
91
  othersTouchPoints[data['user']['id']]=data;
92
 
93
  // just for debugging
 
 
 
 
 
 
 
94
  // WidgetsBinding.instance.addPostFrameCallback((_){
95
  // ScaffoldMessenger.of(context).hideCurrentSnackBar();
96
  // ScaffoldMessenger.of(context).showSnackBar(
@@ -149,132 +154,122 @@ class HomeScreenState extends State<HomeScreen>{
149
 
150
  void connectWebsocket() async{
151
 
152
- try{
153
- channel=WebSocketChannel.connect(Uri.parse(
154
- String.fromEnvironment(
155
  "WS_SERVER_URL",
156
  defaultValue: "ws://localhost:3000"
157
- )
158
-
159
- ));
 
 
160
 
161
- await channel.ready; // after this we are connected to the server
162
- }
163
- catch(e){
164
- print("Can't connect to the web socket server");
165
  return;
166
  }
167
-
168
- // test connection
169
  Object data = {
170
  "route":"test_connection"
171
  };
172
  channel.sink.add(json.encode(data));
 
 
173
 
174
- channel.stream.listen((message) {
175
- // message.get
176
- Map map;
177
- final String type;
178
- try{
179
- map = jsonDecode(message);
180
- }
181
- catch(e){
182
- print("can't decode to json:\t"+message);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  return;
184
  }
 
 
 
185
 
186
- // if any error found do nothing
187
- if(map.containsKey("error")){
188
- print(map);
189
- return;
190
- }
191
 
192
- type = map["message"];
193
-
194
- if(type=="test_connection_response"){
195
- // testing connection
196
- print("test_connection successful");
197
-
198
- }
199
- else if(type=="join_room_response"){
200
- print(map);
201
- }
202
- else if(type=="set_username_response"){
203
- print(map);
204
  setState(() {
205
- userid=map['user']['id'];
206
  });
207
  }
208
- else if(type=="get_rooms_response"){
209
- print(map);
210
- }
211
- else if(type=="room_update"){
212
- print(map);
213
- enterRoom(map);
214
- }
215
- else if(type=="send_vibration_response"){ // handles when we send_touch without being in a room
216
- print(map);
217
- ScaffoldMessenger.of(context).hideCurrentSnackBar();
218
- ScaffoldMessenger.of(context).showSnackBar(
219
- SnackBar(
220
- content:Text(map['status'])
221
- )
222
- );
223
- }
224
- else if(type=="receive_touch"){
225
- if(map['user']['id']==userid){
226
- // ignore this
227
- // print("self touch received. Ignore this");
228
- return;
229
- }
230
-
231
- // touch received to update othersTouchPoints
232
- // print(map);
233
-
234
- if(map['type']=='enabled'){ // add touch point
235
-
236
- // static width and height
237
- double staticHeight=getHeaderHeight()!+outsidepadding*2; // this is the extra static height which change with resize
238
- double staticWidth=outsidepadding*2; // this is the extra static height which change with resize
239
-
240
- // rescale point according to the screen
241
- map['position']['x']*=width-staticWidth;
242
- map['position']['y']*=height-staticHeight;
243
-
244
- // print(map['position']['x'].toString());
245
- // print(map['position']['y'].toString());
246
- setState(() {
247
- othersTouchPoints[map['id']]=map;
248
- });
249
- }
250
- else{// delete the touch point
251
- setState(() {
252
- othersTouchPoints.remove(map['id']);
253
- });
254
- }
255
-
256
  }
257
-
258
- });
259
 
260
- }
261
 
 
262
 
263
  void setUsername() async{
264
  prefs = await SharedPreferences.getInstance();
265
- try{
266
- await channel.ready;
267
- }
268
- catch(e){
269
- print("Can't connect to the web socket server");
270
  return;
271
  }
272
-
273
  // set username
274
  Map data = {
275
  "route": "set_username",
276
  "username": prefs.getString("username"),
277
  };
 
278
  channel.sink.add(json.encode(data));
279
 
280
  }
@@ -305,11 +300,7 @@ class HomeScreenState extends State<HomeScreen>{
305
  // it is used to create a room in server
306
  Map data;
307
 
308
- try{
309
- await channel.ready;
310
- }
311
- catch(e){
312
- print("Can't connect to the web socket server");
313
  return;
314
  }
315
 
@@ -455,11 +446,7 @@ class HomeScreenState extends State<HomeScreen>{
455
  double staticHeight=getHeaderHeight()!+outsidepadding*2; // this is the extra static height which change with resize
456
  double staticWidth=outsidepadding*2; // this is the extra static height which change with resize
457
 
458
- try{
459
- await channel.ready;
460
- }
461
- catch(e){
462
- print("Can't connect to the web socket server");
463
  return;
464
  }
465
  data={
@@ -486,11 +473,7 @@ class HomeScreenState extends State<HomeScreen>{
486
  sendTouchScheduler.cancel();
487
  // send one last touch to tell touch is ended
488
  Map data;
489
- try{
490
- await channel.ready;
491
- }
492
- catch(e){
493
- print("Can't connect to the web socket server");
494
  return;
495
  }
496
  data={
@@ -796,39 +779,45 @@ class HomeScreenState extends State<HomeScreen>{
796
  color:const Color.fromARGB(255, 67, 67, 67),
797
  borderRadius: BorderRadius.circular(40),
798
  ),
799
- child: ListView.builder(
800
- itemCount: roomidList.length,
801
- itemBuilder: ((context, index){
802
- return Row(
803
- mainAxisAlignment: MainAxisAlignment.center,
804
- // crossAxisAlignment: CrossAxisAlignment.stretch,
805
- children: [
806
- Expanded(
807
- child: Container(
808
- padding:EdgeInsets.all(8),
809
- decoration: BoxDecoration(
810
- // border:Border(
811
- // bottom:BorderSide(
812
- // color:Color.fromRGBO(200, 200, 200, 1),
813
- // width: 4
814
- // ),
815
- // ),
816
- ),
817
- child: Text(
818
- roomnameList[index],
819
- textAlign:TextAlign.center,
820
- maxLines: 1,
821
- style:TextStyle(
822
- fontSize:20,
823
- overflow: TextOverflow.clip,
 
 
 
 
 
 
824
 
825
- ),
826
- )
827
- ),
828
- ),
829
- ],
830
- );
831
- })),
832
  curve: Curves.easeIn,
833
  ),
834
  ),
 
7
  import 'package:web_socket_channel/web_socket_channel.dart';
8
  import 'package:web_socket_channel/status.dart' as status;
9
 
10
+ import 'ws_server_connection_handler.dart';
11
+
12
  import 'package:flutter_colorpicker/flutter_colorpicker.dart';
13
 
14
  import 'package:flutter/foundation.dart' show kIsWeb; // to check of platform is web
 
38
  }
39
 
40
  class HomeScreenState extends State<HomeScreen>{
41
+ late Custom_ws_channel channel;
42
  late double width,height;
43
  late SharedPreferences prefs;
44
  double containerHeight = 0,containerWidth=0;
 
72
 
73
  // roomidList=["1","2"];
74
  // roomnameList=["room 1","room 2"];
 
 
 
 
75
 
76
  Map data={
77
  "user": {
 
89
  othersTouchPoints[data['user']['id']]=data;
90
 
91
  // just for debugging
92
+ WidgetsBinding.instance.addPostFrameCallback((_){
93
+ getPreferences();
94
+ // setPreferences();
95
+ connectWebsocket();
96
+ setUsername();
97
+ });
98
+
99
  // WidgetsBinding.instance.addPostFrameCallback((_){
100
  // ScaffoldMessenger.of(context).hideCurrentSnackBar();
101
  // ScaffoldMessenger.of(context).showSnackBar(
 
154
 
155
  void connectWebsocket() async{
156
 
157
+ channel=Custom_ws_channel(
158
+ const String.fromEnvironment(
 
159
  "WS_SERVER_URL",
160
  defaultValue: "ws://localhost:3000"
161
+ ),
162
+ onMessage: response_handler,
163
+ // onMessage: (value){},
164
+ onErrorShowMessage:(msg,e){showSnackBar(msg);},
165
+ );
166
 
167
+ if(!await channel.isConnected()){
 
 
 
168
  return;
169
  }
 
 
170
  Object data = {
171
  "route":"test_connection"
172
  };
173
  channel.sink.add(json.encode(data));
174
+
175
+ }
176
 
177
+ void response_handler(message) {
178
+ // message.get
179
+ Map map;
180
+ final String type;
181
+ try{
182
+ map = jsonDecode(message);
183
+ }
184
+ catch(e){
185
+ print("can't decode to json:\t"+message);
186
+ return;
187
+ }
188
+
189
+ // if any error found do nothing
190
+ if(map.containsKey("error")){
191
+ print(map);
192
+ return;
193
+ }
194
+
195
+ type = map["message"];
196
+
197
+ if(type=="test_connection_response"){
198
+ // testing connection
199
+ print("test_connection successful");
200
+
201
+ }
202
+ else if(type=="join_room_response"){
203
+ print(map);
204
+ }
205
+ else if(type=="set_username_response"){
206
+ print(map);
207
+ setState(() {
208
+ userid=map['user']['id'];
209
+ });
210
+ }
211
+ else if(type=="get_rooms_response"){
212
+ print(map);
213
+ }
214
+ else if(type=="room_update"){
215
+ print(map);
216
+ enterRoom(map);
217
+ }
218
+ else if(type=="send_vibration_response"){ // handles when we send_touch without being in a room
219
+ print(map);
220
+ showSnackBar(map['status']);
221
+ setState(() {
222
+ currRoomId="";
223
+ currRoomName="";
224
+ });
225
+ }
226
+ else if(type=="receive_touch"){
227
+ if(map['user']['id']==userid){
228
+ // ignore this
229
+ // print("self touch received. Ignore this");
230
  return;
231
  }
232
+
233
+ // touch received to update othersTouchPoints
234
+ // print(map);
235
 
236
+ if(map['type']=='enabled'){ // add touch point
 
 
 
 
237
 
238
+ // static width and height
239
+ double staticHeight=getHeaderHeight()!+outsidepadding*2; // this is the extra static height which change with resize
240
+ double staticWidth=outsidepadding*2; // this is the extra static height which change with resize
241
+
242
+ // rescale point according to the screen
243
+ map['position']['x']*=width-staticWidth;
244
+ map['position']['y']*=height-staticHeight;
245
+
246
+ // print(map['position']['x'].toString());
247
+ // print(map['position']['y'].toString());
 
 
248
  setState(() {
249
+ othersTouchPoints[map['id']]=map;
250
  });
251
  }
252
+ else{// delete the touch point
253
+ setState(() {
254
+ othersTouchPoints.remove(map['id']);
255
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
256
  }
 
 
257
 
258
+ }
259
 
260
+ }
261
 
262
  void setUsername() async{
263
  prefs = await SharedPreferences.getInstance();
264
+ if(!await channel.isConnected()){
 
 
 
 
265
  return;
266
  }
 
267
  // set username
268
  Map data = {
269
  "route": "set_username",
270
  "username": prefs.getString("username"),
271
  };
272
+
273
  channel.sink.add(json.encode(data));
274
 
275
  }
 
300
  // it is used to create a room in server
301
  Map data;
302
 
303
+ if(!await channel.isConnected()){
 
 
 
 
304
  return;
305
  }
306
 
 
446
  double staticHeight=getHeaderHeight()!+outsidepadding*2; // this is the extra static height which change with resize
447
  double staticWidth=outsidepadding*2; // this is the extra static height which change with resize
448
 
449
+ if(!await channel.isConnected()){
 
 
 
 
450
  return;
451
  }
452
  data={
 
473
  sendTouchScheduler.cancel();
474
  // send one last touch to tell touch is ended
475
  Map data;
476
+ if(!await channel.isConnected()){
 
 
 
 
477
  return;
478
  }
479
  data={
 
779
  color:const Color.fromARGB(255, 67, 67, 67),
780
  borderRadius: BorderRadius.circular(40),
781
  ),
782
+ // child:TextFormField(
783
+ // initialValue:currRoomId,
784
+ // // decoration: InputDecoration(
785
+ // // val
786
+ // // ),
787
+ // ),
788
+ // child: ListView.builder(
789
+ // itemCount: roomidList.length,
790
+ // itemBuilder: ((context, index){
791
+ // return Row(
792
+ // mainAxisAlignment: MainAxisAlignment.center,
793
+ // // crossAxisAlignment: CrossAxisAlignment.stretch,
794
+ // children: [
795
+ // Expanded(
796
+ // child: Container(
797
+ // padding:EdgeInsets.all(8),
798
+ // decoration: BoxDecoration(
799
+ // // border:Border(
800
+ // // bottom:BorderSide(
801
+ // // color:Color.fromRGBO(200, 200, 200, 1),
802
+ // // width: 4
803
+ // // ),
804
+ // // ),
805
+ // ),
806
+ // child: Text(
807
+ // roomnameList[index],
808
+ // textAlign:TextAlign.center,
809
+ // maxLines: 1,
810
+ // style:TextStyle(
811
+ // fontSize:20,
812
+ // overflow: TextOverflow.clip,
813
 
814
+ // ),
815
+ // )
816
+ // ),
817
+ // ),
818
+ // ],
819
+ // );
820
+ // })),
821
  curve: Curves.easeIn,
822
  ),
823
  ),
client/lib/ws_server_connection_handler.dart ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import 'package:web_socket_channel/web_socket_channel.dart';
2
+ import 'package:web_socket_channel/status.dart' as status;
3
+
4
+ class Custom_ws_channel{
5
+ late WebSocketChannel channel;
6
+ bool webSocketConnected=false;
7
+ int reconnectAttempts=0;
8
+ String serverUrl;
9
+ late Uri serverUri;
10
+ int delay;
11
+ void Function(dynamic) onMessage;
12
+ void Function(String,dynamic) onErrorShowMessage;
13
+
14
+
15
+ Custom_ws_channel(this.serverUrl,{this.delay=5,required this.onMessage,required this.onErrorShowMessage}){
16
+ serverUri=Uri.parse(serverUrl);
17
+ connect();
18
+ }
19
+
20
+ get sink => channel.sink;
21
+ get ready =>channel.ready;
22
+
23
+ Future<bool> isConnected() async{
24
+ try{
25
+ await channel.ready;
26
+ return true;
27
+ }
28
+ catch(e){
29
+ debugFn("we are not connected");
30
+ return false;
31
+ }
32
+ }
33
+
34
+ void onDone() async{
35
+ debugFn("Reconnecting in $delay seconds, attempt $reconnectAttempts ");
36
+ webSocketConnected=false;
37
+ // channel = null;
38
+ channel.sink.close(status.goingAway); // close old connection
39
+ await Future.delayed(Duration(seconds: delay));
40
+ connect();
41
+ }
42
+ void onError(error){
43
+ debugFn("Error while connecting.",e:error);
44
+ reconnectAttempts += 1;
45
+ }
46
+
47
+ void connect() async{
48
+
49
+ try{
50
+ channel=WebSocketChannel.connect(
51
+ serverUri
52
+ );
53
+
54
+ channel.stream.listen(onMessage, onDone:onDone, onError:onError);
55
+ // channel.stream.listen(onMessage, onError:onError);
56
+ await channel.ready;
57
+ debugFn("connected");
58
+ }
59
+ catch(e){
60
+ debugFn("can't connect to the server",e:e);
61
+ }
62
+
63
+
64
+ }
65
+
66
+
67
+ void debugFn(String s,{e=""}){
68
+ // print("space");
69
+ // print("Custom Message:"+s);
70
+ // print("Custom Error:"+e.toString());
71
+
72
+ onErrorShowMessage(s,e);
73
+
74
+ }
75
+ }