export const useWebhook = (
path: string,
onDisconnect?: () => void,
override?: WebhookOverride
): WebhookHookOutput => {
const cache = useGlobalCache()
const { accessToken, userId } = override ?? cache
const [connectedUserId, setConnectedUserId] = useState<string>()
const [attempts, setAttempts] = useState<number>(1)
const [isConnected, setIsConnected] = useState(false)
const [isLogged, setIsLogged] = useState(false)
const [socket, setSocket] = useState<Socket>()
useEffect(() => {
if (!userId || (connectedUserId && connectedUserId !== userId)) {
setConnectedUserId(undefined)
setIsConnected(false)
setSocket(undefined)
return
}
if (!socket) {
setSocket(
accessToken && accessToken.length && tokenStillValid(accessToken)
? io(`${process.env.baseurl}${path}`, {
path,
transports: ["websocket"],
auth: {
Authorization: `Bearer ${accessToken}`
},
extraHeaders: socketConfig.extraHeaders,
autoConnect: false
})
: undefined
)
setIsLogged(!!accessToken && !!accessToken.length)
setConnectedUserId(userId)
}
}, [accessToken, connectedUserId, path, socket, userId])
useEffect(() => {
if (socket) {
socket.on("connect", () => {
setIsConnected(true)
setAttempts(0)
})
socket.on("disconnect", () => {
onDisconnect?.()
setIsConnected(false)
setSocket(undefined)
})
socket.connect()
return () => {
socket.off("connect")
socket.off("disconnect")
socket.disconnect()
}
}
}, [onDisconnect, socket])
useEffect(() => {
if (socket && !isConnected && attempts < 10) {
socket.connect()
const interval = setTimeout(() => {
setAttempts(attempts + 1)
}, 5000)
return () => clearInterval(interval)
}
}, [isConnected, attempts, socket])
return useMemo(
// memo necessary to avoid app wide rerenders
() => ({
isConnected: isConnected || attempts === 0,
isLogged,
socket,
setSocket,
userId
}),
[isConnected, isLogged, attempts, socket, userId]
)
}
同一套程序,web端可以正常連接到websocket服務(wù)器,而如果是react-native則會報服務(wù)器內(nèi)部錯誤,剛開始我以為是https證書的問題,本地模擬了一個https服務(wù),結(jié)果也能正常訪問,最后發(fā)現(xiàn)是服務(wù)器防火墻拒絕了訪問,
Firewall 拒絕沒有 User-Agent 字段的訪問通常是出于安全和篩選流量的考慮。User-Agent 字符串在 HTTP 請求中扮演重要角色,它提供了關(guān)于發(fā)起請求的客戶端(如瀏覽器或應(yīng)用程序)的信息。以下是一些原因,說明為什么缺少 User-Agent 可能導(dǎo)致 Firewall 拒絕訪問:
- 安全篩選
識別惡意軟件:某些惡意軟件和爬蟲可能不發(fā)送標(biāo)準(zhǔn)的 User-Agent 字符串。Firewalls 和安全系統(tǒng)可能會拒絕沒有 User-Agent 的請求,以防止此類惡意活動。
防止自動化攻擊:自動化的網(wǎng)絡(luò)攻擊(如 DDoS 攻擊)可能不會包括 User-Agent 字符串。拒絕這些請求可以作為一種防御措施。 - 流量管理
區(qū)分人類和非人類流量:沒有 User-Agent 的請求可能被視為非人類流量(如腳本或爬蟲),而某些服務(wù)可能只想為人類用戶提供服務(wù)。
分析和日志記錄:User-Agent 信息對于理解和分析網(wǎng)站流量至關(guān)重要。缺少此信息可能使得流量管理和日志記錄變得更加困難。 - 兼容性和規(guī)范
遵守協(xié)議:雖然 HTTP 規(guī)范沒有強(qiáng)制要求每個請求都必須包含 User-Agent 字段,但許多網(wǎng)站和應(yīng)用仍然期望它,并可能基于此設(shè)計了安全策略。
確保內(nèi)容適配:在某些情況下,服務(wù)器可能根據(jù) User-Agent 來決定發(fā)送什么樣的內(nèi)容或格式。 - 配置和策略
特定的網(wǎng)絡(luò)策略:某些網(wǎng)絡(luò)環(huán)境或組織可能有特定的策略,要求所有請求都必須包含 User-Agent 字段,作為訪問控制的一部分。