Skip to content

Commit

Permalink
Webscoket reconnecting
Browse files Browse the repository at this point in the history
  • Loading branch information
diyahir committed Mar 12, 2024
1 parent 6d6061f commit b59facb
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 44 deletions.
38 changes: 3 additions & 35 deletions packages/nextjs/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
"use client";

import React, { useCallback, useRef, useState } from "react";
import React from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { Bars3Icon } from "@heroicons/react/24/outline";
import { FaucetButton, RainbowKitCustomConnectButton } from "~~/components/scaffold-eth";
import { useLightningApp } from "~~/hooks/LightningProvider";
import { useOutsideClick } from "~~/hooks/scaffold-eth";

type HeaderMenuLink = {
label: string;
Expand Down Expand Up @@ -56,47 +54,17 @@ export const HeaderMenuLinks = () => {
* Site header
*/
export const Header = () => {
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
const burgerMenuRef = useRef<HTMLDivElement>(null);
useOutsideClick(
burgerMenuRef,
useCallback(() => setIsDrawerOpen(false), []),
);

const { isWebSocketConnected, reconnect } = useLightningApp();
return (
<div className="sticky font-plex lg:static top-0 navbar bg-base-100 min-h-0 flex-shrink-0 justify-between z-20 px-0 sm:px-2">
<div className="navbar-start w-auto lg:w-1/2">
<div className="lg:hidden dropdown" ref={burgerMenuRef}>
<label
tabIndex={0}
className={`ml-1 btn btn-ghost ${isDrawerOpen ? "hover:bg-secondary" : "hover:bg-transparent"}`}
onClick={() => {
setIsDrawerOpen(prevIsOpenState => !prevIsOpenState);
}}
>
<Bars3Icon className="h-1/2" />
</label>
{isDrawerOpen && (
<ul
tabIndex={0}
className="menu menu-compact dropdown-content mt-3 p-2 shadow bg-base-100 rounded-box w-52"
onClick={() => {
setIsDrawerOpen(false);
}}
>
<HeaderMenuLinks />
</ul>
)}
</div>

<Link color={"white"} href="/" passHref className="hidden lg:flex items-center gap-2 ml-4 mr-6 shrink-0">
<img src="/logo.svg" alt="Botanix Logo" width={"24px"} height={"24px"} />
<div className="flex flex-col font-plex font-bold text-white">Botanix {"<>"} Lightning </div>
</Link>
<ul className="hidden lg:flex lg:flex-nowrap menu menu-horizontal px-1 gap-2">
{/* <ul className="hidden lg:flex lg:flex-nowrap menu menu-horizontal px-1 gap-2">
<HeaderMenuLinks />
</ul>
</ul> */}
</div>
<div className="navbar-end flex-grow mr-4">
{/* a div that shows if the client is connected to the server */}
Expand Down
41 changes: 32 additions & 9 deletions packages/nextjs/hooks/useWebSocket.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,62 @@
// src/hooks/useWebSocket.ts
import { useCallback, useEffect, useRef, useState } from "react";
import { InvoiceRequest, InvoiceResponse } from "~~/types/utils";

export const useWebSocket = (url: string) => {
// return { sendMessage: useCallback(() => {}, []), data: null, error: null, isOpen: false };
const socket = useRef<WebSocket | null>(null);
const [data, setData] = useState<InvoiceResponse | null>(null);
const [error, setError] = useState<Event | null>(null);
const [isWebSocketConnected, setIsWebSocketConnected] = useState<boolean>(false);
const reconnectInterval = useRef<NodeJS.Timeout | null>(null);

const checkAndReconnect = () => {
if (!isWebSocketConnected) {
console.log("Reconnecting WebSocket...");
reconnect();
}
};

const reconnect = () => {
if (socket.current) {
socket.current.close();
}
socket.current = new WebSocket(url);
setIsWebSocketConnected(true);
initializeWebSocket();
};

useEffect(() => {
const initializeWebSocket = () => {
socket.current = new WebSocket(url);

socket.current.onopen = () => setIsWebSocketConnected(true);
socket.current.onclose = () => setIsWebSocketConnected(false);
socket.current.onopen = () => {
setIsWebSocketConnected(true);
if (reconnectInterval.current) {
clearInterval(reconnectInterval.current);
}
};
socket.current.onclose = () => {
setIsWebSocketConnected(false);
if (!reconnectInterval.current) {
reconnectInterval.current = setInterval(checkAndReconnect, 6000); // 20 seconds
}
};
socket.current.onerror = event => setError(event);
socket.current.onmessage = event => {
try {
console.log("Received message:", event.data);
const responseData: InvoiceResponse = JSON.parse(event.data);
setData(responseData);
} catch (err) {
console.error("Failed to parse message", err);
}
};
};

useEffect(() => {
initializeWebSocket();
return () => {
socket.current?.close();
if (socket.current) {
socket.current.close();
}
if (reconnectInterval.current) {
clearInterval(reconnectInterval.current);
}
};
}, [url]);

Expand Down

0 comments on commit b59facb

Please sign in to comment.