olofd / react-native-signalr

Use SignalR with React Native
150 stars 61 forks source link

On Screen Change, Event Is Still fired #65

Open hemalrathod opened 3 years ago

hemalrathod commented 3 years ago

In React Native, when I leave the screen, when server calls the method of that screen, it still fires on mobile app. Also if I go back to same screen again, the event is registered for second time and the react native screen event fires for 2 times when invoked from server.

Also while receiving data from server, I do find some chokking/hanging/freezing on data sending or receiving. I don't know why this happens.

pankajdreamsoft commented 3 years ago

Anyone have any solution on this problem? I am facing same issue still on the server side it's hanging.

kadirguloglu commented 3 years ago

Anyone have any solution on this problem? I am facing same issue still on the server side it's hanging.

My problems were solved with package @microsoft/signalr

pankajdreamsoft commented 3 years ago

Ooo.. that's cool ... let me check with this npm (@microsoft/signalr) package.

pankajdreamsoft commented 3 years ago

@kadirguloglu: Is this NPM available for React Native Mobile app ? As i checked it's available for Node.js, Browser, WebWorker. So could use in mobile App (React Native).

kadirguloglu commented 3 years ago

yes it can be used and it works well. I have tested. I have apps @pankajdreamsoft

VijaySharma12 commented 3 years ago

Send me Your demo code @kadirguloglu

kadirguloglu commented 3 years ago

@VijaySharma12 @pankajdreamsoft

import React, { useEffect, useState, useRef } from "react";
import { HubConnectionBuilder, LogLevel, HubConnectionState } from "@microsoft/signalr";
import { useDispatch, useSelector } from "react-redux";
import {
  View,
  Image,
  Text,
  Platform,
  StyleSheet,
  Dimensions,
  LogBox,
  AppState,
} from "react-native";

import { signalRUrl } from "../helpers/variables";
import { beniGetir } from "../helpers/functions";
import useInterval from "../hooks/useInterval";
import { Native } from "sentry-expo";

import { eczaneKullanicilari } from "../business/action/kullanici";
import SignalRContext from "../business/context/signalR.context";

import BigButton from "../components/BigButton";

import {
  IpControlResponse,
  SignalRProxy as SignalRProxyT,
  SignalRConnection,
  SignalRException,
  SignalRConnecting,
  SignalRSon10ReceteCevaplandi,
  SignalRConnectionId,
  SignalRReceteBelgeCevaplandi,
  SignalRKarekodGonderimiCevaplandi,
  SignalRKasaCevaplandi,
  SignalRKasaCevaplandiHata,
  SignalRSon10ReceteCevaplandiHata,
} from "../business/types/signalr";

const { width, height } = Dimensions.get("window");

const SignalrProvider = ({ children, isTest }) => {
  LogBox.ignoreAllLogs();
  const appState = useRef(AppState.currentState);
  const dispatch = useDispatch();
  const [connecting, setConnecting] = useState(true);
  const [stateConnection, setStateConnection] = useState(false);
  const [signalRConnecting, setSignalRConnecting] = useState(true);
  const [sConnection, setSConnection] = useState(null);
  const [appStateS, setAppStateS] = useState(null);

  const { SignalRProxy } = useSelector((x) => x.signalr);
  const { eczaneKullanicilariResult } = useSelector((x) => x.kullanici);
  const { iPControlResult } = useSelector((x) => x.eczane);
  const { currentUser } = useSelector((x) => x.context);

  useEffect(() => {
    const subscription = AppState.addEventListener("change", (nextAppState) => {
      if (appState.current.match(/inactive|background/) && nextAppState === "active") {
      }

      appState.current = nextAppState;
      setAppStateS(appState.current);
    });

    return () => {
      subscription?.remove();
    };
  }, []);

  useInterval(() => {
    if (iPControlResult && iPControlResult.Veri && iPControlResult.Veri.PEId) {
      dispatch(eczaneKullanicilari(iPControlResult.Veri.PEId));
    } else {
      if (
        eczaneKullanicilariResult &&
        eczaneKullanicilariResult.Veri &&
        currentUser &&
        currentUser.GLN
      ) {
        let aktifKullanici = beniGetir(eczaneKullanicilariResult.Veri, currentUser.GLN);
        if (aktifKullanici && aktifKullanici.PKPEId) {
          dispatch(eczaneKullanicilari(aktifKullanici.PKPEId));
        }
      }
    }
  }, 60000);

  useEffect(() => {
    if (appStateS != null) {
      if (sConnection?.connectionState == "Disconnected") signalRBaglan(currentUser);
      if (sConnection == null) signalRBaglan(currentUser);
    }
    return () => {};
  }, [appStateS]);

  async function signalRBaglan(user, afterConnection) {
    if (user) {
      let connectionUrl = signalRUrl + `?PKId=${user.PKId}&PEId=${user.PEId}`;
      if (sConnection != null && sConnection.connection.baseUrl != connectionUrl) {
        await sConnection.stop();
        setSConnection(null);
      }
      if (
        (sConnection === null && connectionUrl.indexOf("PKId") > -1) ||
        (connectionUrl.indexOf("PKId") > -1 && sConnection?.connectionState == "Disconnected")
      ) {
        let connection = null;
        setConnecting(true);
        setSignalRConnecting(true);
        dispatch({
          type: SignalRConnecting,
          payload: {
            data: true,
          },
        });
        try {
          connection = new HubConnectionBuilder()
            .withUrl(connectionUrl)
            .configureLogging(LogLevel.Error)
            .withAutomaticReconnect([5, 15, 25, 35, 45, 55])
            .build();

          connection.on("IpControlResponse", (data) => {
            dispatch({
              type: IpControlResponse,
              payload: {
                data: data,
              },
            });
          });

          connection.on("Son10ReceteCevaplandi", (receteler) => {
            dispatch({
              type: SignalRSon10ReceteCevaplandi,
              payload: {
                data: {
                  receteler: receteler,
                },
              },
            });
          });

          connection.on("ReceteBelgeCevaplandi", (belgelerKaydedildiMi) => {
            dispatch({
              type: SignalRReceteBelgeCevaplandi,
              payload: {
                data: {
                  belgelerKaydedildiMi: belgelerKaydedildiMi,
                },
              },
            });
          });

          connection.on("KarekodGonderimiCevaplandi", (karekodlarKaydedildiMi) => {
            dispatch({
              type: SignalRKarekodGonderimiCevaplandi,
              payload: {
                data: {
                  karekodlarKaydedildiMi: karekodlarKaydedildiMi,
                },
              },
            });
          });

          connection.on("KasaCevaplandi", (data, kasalar) => {
            dispatch({
              type: SignalRKasaCevaplandi,
              payload: {
                data: data,
              },
            });
          });

          connection.on("KasaCevaplandiHata", () => {
            dispatch({
              type: SignalRKasaCevaplandiHata,
              payload: {
                data: true,
              },
            });
          });

          connection.on("Son10ReceteCevaplandiHata", () => {
            dispatch({
              type: SignalRSon10ReceteCevaplandiHata,
              payload: {
                data: true,
              },
            });
          });

          connection.onclose = function (err) {
            Native.captureMessage(
              JSON.stringify({ errorType: "signalr connection.onclose", exception: err })
            );
          };

          connection.on("OturumAcildi", (acanKullanici) => {
            // let kullaniciListesiCopy = [].concat(eczaneKullanicilariResult);
            // for (i = 0; i < kullaniciListesiCopy.length; i++) {
            //   let pk = kullaniciListesiCopy[i];
            //   if (pk.PKId === acanKullanici.PKId) {
            //     kullaniciListesiCopy[i] = acanKullanici;
            //   }
            // }
            // dispatch({
            //   type: ECZANE_KULLANICILARI_SUCCESS,
            //   payload: {
            //     data: {
            //       Veri: kullaniciListesiCopy,
            //       Basarili: true,
            //     },
            //   },
            // });
          });

          // connection.on("OturumKapandi", (kapatanKullanici) => {
          //   let kullaniciListesiCopy = [].concat(eczaneKullanicilariResult);
          //   for (i = 0; i < kullaniciListesiCopy.length; i++) {
          //     let pk = kullaniciListesiCopy[i];
          //     if (pk.PKId === kapatanKullanici.PKId) {
          //       kullaniciListesiCopy[i] = kapatanKullanici;
          //     }
          //   }
          //   dispatch({
          //     type: ECZANE_KULLANICILARI_SUCCESS,
          //     payload: {
          //       data: {
          //         Veri: kullaniciListesiCopy,
          //         Basarili: true,
          //       },
          //     },
          //   });
          // });

          // connection.on("kasaCevaplandi", (data) => {
          //   dispatch({
          //     type: BotrasSignalRKasaCevaplandi,
          //     payload: {
          //       data: data,
          //     },
          //   });
          // });

          let signalRConnectionResult = await connection
            .start()
            .then(function () {
              setSConnection(connection);
              setConnecting(false);
              setStateConnection(true);
              dispatch({
                type: SignalRConnection,
                payload: {
                  data: true,
                },
              });
              dispatch({
                type: SignalRConnecting,
                payload: {
                  data: false,
                },
              });
              dispatch({
                type: SignalRConnectionId,
                payload: {
                  data: connection.connectionId,
                },
              });
              dispatch({
                type: SignalRProxyT,
                payload: {
                  data: connection,
                },
              });
              setSignalRConnecting(false);
              if (afterConnection) {
                afterConnection(true);
              }
            })
            .catch(function (e) {
              Native.captureMessage(
                JSON.stringify({ errorType: "signalrConnectionError", exception: e })
              );
              dispatch({
                type: SignalRException,
                payload: {
                  data: e,
                },
              });
              dispatch({
                type: SignalRConnecting,
                payload: {
                  data: false,
                },
              });
              setSignalRConnecting(false);
              dispatch({
                type: SignalRConnection,
                payload: {
                  data: false,
                },
              });
              dispatch({
                type: SignalRProxyT,
                payload: {
                  data: null,
                },
              });
              setConnecting(false);
              setStateConnection(false);
              if (afterConnection) {
                afterConnection(false);
              }
            });
          Native.captureMessage(
            JSON.stringify({
              errorType: "signalRConnectionResult",
              exception: signalRConnectionResult,
            })
          );
        } catch (error) {}
      } else if (sConnection != null) {
        if (sConnection.connection.connectionState == HubConnectionState.Connected) {
          if (afterConnection) {
            afterConnection(true);
          }
        }
      }
    }
  }

  // if (isTest)
  //   return (
  //     <SignalRContext.Provider
  //       value={{ signalRBaglan: signalRBaglan, connection: sConnection }}
  //     >
  //       {children}
  //     </SignalRContext.Provider>
  //   );

  // if (signalRConnecting && signalRConnecting === true) {
  //   return (
  //     <View style={styles.uyariView}>
  //       <Image
  //         source={require("../assets/21680-connecting.gif")}
  //         style={styles.uyariResim}
  //       />
  //       <Text style={styles.uyariYazi}>Bağlantınız kontrol ediliyor</Text>
  //     </View>
  //   );
  // }

  // if (connecting === true) {
  //   return (
  //     <View style={styles.uyariView}>
  //       <Image
  //         source={require("../assets/21680-connecting.gif")}
  //         style={styles.uyariResim}
  //       />
  //       <Text style={styles.uyariYazi}>Bağlantınız kontrol ediliyor</Text>
  //     </View>
  //   );
  // }

  // if (!SignalRProxy) {
  //   return (
  //     <View style={styles.uyariView}>
  //       <Image
  //         source={require("../assets/10110-sad.gif")}
  //         style={styles.uyariResim}
  //       />
  //       <Text style={styles.uyariYazi}>Bağlantı sırasında bir hata oluştu</Text>
  //       <BigButton
  //         title="Tekrar Bağlan"
  //         onPress={() => {
  //           setSConnection(null);
  //           // signalRBaglan();
  //         }}
  //       />
  //     </View>
  //   );
  // }

  // if (!stateConnection) {
  //   return (
  //     <View style={styles.uyariView}>
  //       <Image
  //         source={require("../assets/10110-sad.gif")}
  //         style={styles.uyariResim}
  //       />
  //       <Text style={styles.uyariYazi}>Bağlantı sırasında bir hata oluştu</Text>
  //       <BigButton
  //         title="Tekrar Bağlan"
  //         onPress={() => {
  //           signalRBaglan();
  //         }}
  //       />
  //     </View>
  //   );
  // }

  return (
    <SignalRContext.Provider value={{ signalRBaglan: signalRBaglan, connection: sConnection }}>
      {children}
    </SignalRContext.Provider>
  );
};

export default SignalrProvider;

const styles = StyleSheet.create({
  uyariView: {
    flex: 1,
    flexDirection: "column",
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "#fff",
  },
  uyariResim: {
    width: width * 0.7,
    height: height * 0.4,
    resizeMode: "contain",
  },
  uyariYazi: {
    fontSize: 20,
  },
  container: {
    flex: 1,
    padding: 10,
    justifyContent: "center",
  },
  button: {
    marginTop: 10,
  },
  logo: {
    width: width * 0.3,
    height: height * 0.1,
    resizeMode: "contain",
  },
  logoView: {
    flexDirection: "row",
    justifyContent: "center",
    alignItems: "center",
  },
  eczaneContainer: {
    flex: 1,
    flexDirection: "row",
    justifyContent: "space-between",
    alignItems: "center",
    backgroundColor: "white",
    borderColor: "#000",
    padding: 10,
    borderRadius: 15,
    marginBottom: 10,
    ...Platform.select({
      ios: {
        shadowColor: "#000",
        shadowOffset: {
          width: 0,
          height: 4,
        },
        shadowOpacity: 0.3,
        shadowRadius: 4.65,
      },
      default: {
        elevation: 8,
      },
    }),
  },
  txtGlnNumarasi: {
    fontSize: 16,
  },
  txtEczaneAdi: {
    fontSize: 16,
  },
  seciliEczaneOnayResmi: {
    width: 40,
    height: 40,
    resizeMode: "contain",
  },
});