mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
initiating call sequence to contact
This commit is contained in:
parent
11407b0cc6
commit
7a36d4843d
@ -2,6 +2,7 @@ package databag
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"github.com/gorilla/mux"
|
||||||
)
|
)
|
||||||
|
|
||||||
//KeepCall keeps call and signaling alive
|
//KeepCall keeps call and signaling alive
|
||||||
@ -13,11 +14,8 @@ func KeepCall(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var callId string
|
params := mux.Vars(r)
|
||||||
if err := ParseRequest(r, w, &callId); err != nil {
|
callId := params["callId"]
|
||||||
ErrResponse(w, http.StatusBadRequest, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
bridgeRelay.KeepAlive(account.ID, callId);
|
bridgeRelay.KeepAlive(account.ID, callId);
|
||||||
WriteResponse(w, nil);
|
WriteResponse(w, nil);
|
||||||
|
@ -3,16 +3,14 @@ package databag
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"errors"
|
"errors"
|
||||||
|
"github.com/gorilla/mux"
|
||||||
)
|
)
|
||||||
|
|
||||||
//RemoveCall adds an active call with ice signal and relay
|
//RemoveCall adds an active call with ice signal and relay
|
||||||
func RemoveCall(w http.ResponseWriter, r *http.Request) {
|
func RemoveCall(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
var callId string
|
params := mux.Vars(r)
|
||||||
if err := ParseRequest(r, w, &callId); err != nil {
|
callId := params["callId"]
|
||||||
ErrResponse(w, http.StatusBadRequest, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
tokenType := ParamTokenType(r)
|
tokenType := ParamTokenType(r)
|
||||||
if tokenType == APPTokenAgent {
|
if tokenType == APPTokenAgent {
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var bridgeRelay BridgeRelay;
|
var bridgeRelay BridgeRelay;
|
||||||
const BridgeKeepAlive = 6
|
const BridgeKeepAlive = 15
|
||||||
|
|
||||||
type BridgeStatus struct {
|
type BridgeStatus struct {
|
||||||
status string
|
status string
|
||||||
|
@ -800,28 +800,28 @@ var endpoints = routes{
|
|||||||
route{
|
route{
|
||||||
"AddCall",
|
"AddCall",
|
||||||
strings.ToUpper("Post"),
|
strings.ToUpper("Post"),
|
||||||
"/talk/call",
|
"/talk/calls",
|
||||||
AddCall,
|
AddCall,
|
||||||
},
|
},
|
||||||
|
|
||||||
route{
|
route{
|
||||||
"KeepCall",
|
"KeepCall",
|
||||||
strings.ToUpper("Put"),
|
strings.ToUpper("Put"),
|
||||||
"/talk/call/{callId}",
|
"/talk/calls/{callId}",
|
||||||
KeepCall,
|
KeepCall,
|
||||||
},
|
},
|
||||||
|
|
||||||
route{
|
route{
|
||||||
"EndCall",
|
"EndCall",
|
||||||
strings.ToUpper("Delete"),
|
strings.ToUpper("Delete"),
|
||||||
"/talk/call/{callId}",
|
"/talk/calls/{callId}",
|
||||||
EndCall,
|
EndCall,
|
||||||
},
|
},
|
||||||
|
|
||||||
route{
|
route{
|
||||||
"AddRing",
|
"AddRing",
|
||||||
strings.ToUpper("Post"),
|
strings.ToUpper("Post"),
|
||||||
"/talk/ring",
|
"/talk/rings",
|
||||||
AddRing,
|
AddRing,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
10
net/web/src/api/addCall.js
Normal file
10
net/web/src/api/addCall.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||||
|
|
||||||
|
export async function addCall(token, cardId) {
|
||||||
|
let param = "?agent=" + token
|
||||||
|
let call = await fetchWithTimeout('/talk/calls' + param, { method: 'POST', body: JSON.stringify(cardId) });
|
||||||
|
checkResponse(call)
|
||||||
|
let ret = await call.json()
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
@ -6,7 +6,7 @@ export async function addContactRing(server, token, call) {
|
|||||||
host = `https://${server}`
|
host = `https://${server}`
|
||||||
}
|
}
|
||||||
|
|
||||||
let ring = await fetchWithTimeout(`${host}/talk/ring?contact=${token}`, { method: 'POST', body: JSON.stringify(call) });
|
let ring = await fetchWithTimeout(`${host}/talk/rings?contact=${token}`, { method: 'POST', body: JSON.stringify(call) });
|
||||||
checkResponse(ring);
|
checkResponse(ring);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
8
net/web/src/api/keepCall.js
Normal file
8
net/web/src/api/keepCall.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||||
|
|
||||||
|
export async function keepCall(token, callId) {
|
||||||
|
let param = "?agent=" + token
|
||||||
|
let call = await fetchWithTimeout(`/talk/calls/${callId}` + param, { method: 'PUT' });
|
||||||
|
checkResponse(call)
|
||||||
|
}
|
||||||
|
|
8
net/web/src/api/removeCall.js
Normal file
8
net/web/src/api/removeCall.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||||
|
|
||||||
|
export async function removeCall(token, callId) {
|
||||||
|
let param = "?agent=" + token
|
||||||
|
let call = await fetchWithTimeout(`/talk/calls/${callId}` + param, { method: 'DELETE' });
|
||||||
|
checkResponse(call)
|
||||||
|
}
|
||||||
|
|
12
net/web/src/api/removeContactCall.js
Normal file
12
net/web/src/api/removeContactCall.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||||
|
|
||||||
|
export async function removeContactCall(server, token, callId) {
|
||||||
|
let host = "";
|
||||||
|
if (server) {
|
||||||
|
host = `https://${server}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const call = await fetchWithTimeout(`${host}/talk/calls/${callId}?contact=${token}`, { method: 'DELETE' });
|
||||||
|
checkResponse(call);
|
||||||
|
}
|
||||||
|
|
@ -45,12 +45,14 @@ export function useAppContext(websocket) {
|
|||||||
profileContext.actions.setToken(token);
|
profileContext.actions.setToken(token);
|
||||||
cardContext.actions.setToken(token);
|
cardContext.actions.setToken(token);
|
||||||
channelContext.actions.setToken(token);
|
channelContext.actions.setToken(token);
|
||||||
|
ringContext.actions.setToken(token);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
accountContext.actions.clearToken();
|
accountContext.actions.clearToken();
|
||||||
profileContext.actions.clearToken();
|
profileContext.actions.clearToken();
|
||||||
cardContext.actions.clearToken();
|
cardContext.actions.clearToken();
|
||||||
channelContext.actions.clearToken();
|
channelContext.actions.clearToken();
|
||||||
|
ringContext.actions.clearToken();
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
setWebsocket(token);
|
setWebsocket(token);
|
||||||
@ -59,8 +61,8 @@ export function useAppContext(websocket) {
|
|||||||
const clearSession = () => {
|
const clearSession = () => {
|
||||||
uploadContext.actions.clear();
|
uploadContext.actions.clear();
|
||||||
storeContext.actions.clear();
|
storeContext.actions.clear();
|
||||||
ringContext.actions.clear();
|
|
||||||
|
|
||||||
|
ringContext.actions.clearToken();
|
||||||
accountContext.actions.clearToken();
|
accountContext.actions.clearToken();
|
||||||
profileContext.actions.clearToken();
|
profileContext.actions.clearToken();
|
||||||
cardContext.actions.clearToken();
|
cardContext.actions.clearToken();
|
||||||
@ -176,11 +178,9 @@ export function useAppContext(websocket) {
|
|||||||
let activity = JSON.parse(ev.data);
|
let activity = JSON.parse(ev.data);
|
||||||
updateState({ status: 'connected' });
|
updateState({ status: 'connected' });
|
||||||
if (activity.revision) {
|
if (activity.revision) {
|
||||||
console.log("GOR REVISION");
|
|
||||||
setAppRevision(activity.revision);
|
setAppRevision(activity.revision);
|
||||||
}
|
}
|
||||||
if (activity.ring) {
|
if (activity.ring) {
|
||||||
console.log("GOT PHONE!");
|
|
||||||
const { cardId, callId, calleeToken } = activity.ring;
|
const { cardId, callId, calleeToken } = activity.ring;
|
||||||
ringContext.actions.ring(cardId, callId, calleeToken);
|
ringContext.actions.ring(cardId, callId, calleeToken);
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,39 @@
|
|||||||
import { useEffect, useContext, useState, useRef } from 'react';
|
import { useEffect, useContext, useState, useRef } from 'react';
|
||||||
|
import { createWebsocket } from 'api/fetchUtil';
|
||||||
|
import { addContactRing } from 'api/addContactRing';
|
||||||
|
import { addCall } from 'api/addCall';
|
||||||
|
import { keepCall } from 'api/keepCall';
|
||||||
|
import { removeCall } from 'api/removeCall';
|
||||||
|
import { removeContactCall } from 'api/removeContactCall';
|
||||||
|
|
||||||
export function useRingContext() {
|
export function useRingContext() {
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
ringing: new Map(),
|
ringing: new Map(),
|
||||||
|
callStatus: null,
|
||||||
});
|
});
|
||||||
const access = useRef(null);
|
const access = useRef(null);
|
||||||
|
|
||||||
const EXPIRE = 3000000
|
const EXPIRE = 3000000
|
||||||
const ringing = useRef(new Map());
|
const ringing = useRef(new Map());
|
||||||
|
const calling = useRef(null);
|
||||||
|
const ws = useRef(null);
|
||||||
|
|
||||||
const updateState = (value) => {
|
const updateState = (value) => {
|
||||||
setState((s) => ({ ...s, ...value }))
|
setState((s) => ({ ...s, ...value }))
|
||||||
}
|
}
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
clear: () => {
|
setToken: (token) => {
|
||||||
|
if (access.current) {
|
||||||
|
throw new Error("invalid ring state");
|
||||||
|
}
|
||||||
|
access.current = token;
|
||||||
ringing.current = new Map();
|
ringing.current = new Map();
|
||||||
updateState({ ringing: ringing.current });
|
calling.current = null;
|
||||||
|
updateState({ callStatus: null, ringing: ringing.current });
|
||||||
|
},
|
||||||
|
clearToken: () => {
|
||||||
|
access.current = null;
|
||||||
},
|
},
|
||||||
ring: (cardId, callId, calleeToken) => {
|
ring: (cardId, callId, calleeToken) => {
|
||||||
const key = `${cardId}:${callId}`
|
const key = `${cardId}:${callId}`
|
||||||
@ -30,14 +47,11 @@ export function useRingContext() {
|
|||||||
},
|
},
|
||||||
ignore: (cardId, callId) => {
|
ignore: (cardId, callId) => {
|
||||||
const key = `${cardId}:${callId}`
|
const key = `${cardId}:${callId}`
|
||||||
console.log("IGNORE", key);
|
|
||||||
const call = ringing.current.get(key);
|
const call = ringing.current.get(key);
|
||||||
if (call) {
|
if (call) {
|
||||||
call.status = 'ignored'
|
call.status = 'ignored'
|
||||||
ringing.current.set(key, call);
|
ringing.current.set(key, call);
|
||||||
updateState({ ringing: ringing.current });
|
updateState({ ringing: ringing.current });
|
||||||
console.log(ringing.current);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
decline: (cardId, callId) => {
|
decline: (cardId, callId) => {
|
||||||
@ -49,13 +63,109 @@ console.log(ringing.current);
|
|||||||
updateState({ ringing: ringing.current });
|
updateState({ ringing: ringing.current });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
accept: (cardId, callId) => {
|
accept: async (cardId, callId, contactNode, contactToken, calleeToken) => {
|
||||||
|
if (calling.current) {
|
||||||
|
throw new Error("active session");
|
||||||
|
}
|
||||||
|
|
||||||
const key = `${cardId}:${callId}`
|
const key = `${cardId}:${callId}`
|
||||||
const call = ringing.current.get(key);
|
const call = ringing.current.get(key);
|
||||||
if (call) {
|
if (call) {
|
||||||
call.status = 'accepted'
|
call.status = 'accepted'
|
||||||
ringing.current.set(key, call);
|
ringing.current.set(key, call);
|
||||||
updateState({ ringing: ringing.current });
|
updateState({ ringing: ringing.current });
|
||||||
|
|
||||||
|
// connect signal socket
|
||||||
|
calling.current = { state: "connecting", callId, contactNode, contactToken, host: false };
|
||||||
|
updateState({ callStatus: "connecting" });
|
||||||
|
ws.current = createWebsocket(`wss://${contactNode}/signal`);
|
||||||
|
ws.current.onmessage = (ev) => {
|
||||||
|
// handle messages [impolite]
|
||||||
|
console.log(ev);
|
||||||
|
}
|
||||||
|
ws.current.onclose = (e) => {
|
||||||
|
// update state to disconnected
|
||||||
|
calling.current = null;
|
||||||
|
updateState({ calling: null });
|
||||||
|
}
|
||||||
|
ws.current.onopen = () => {
|
||||||
|
calling.current.state = "connected"
|
||||||
|
updateState({ callStatus: "connected" });
|
||||||
|
ws.current.send(JSON.stringify({ AppToken: calleeToken }))
|
||||||
|
}
|
||||||
|
ws.current.error = (e) => {
|
||||||
|
console.log(e)
|
||||||
|
ws.current.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
end: async () => {
|
||||||
|
if (!calling.current) {
|
||||||
|
throw new Error('inactive session');
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const { host, callId, contactNode, contactToken } = calling.current;
|
||||||
|
if (host) {
|
||||||
|
await removeCall(access.current, callId);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
await removeContactCall(contactNode, contactToken, callId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
ws.current.close();
|
||||||
|
},
|
||||||
|
call: async (cardId, contactNode, contactToken) => {
|
||||||
|
if (calling.current) {
|
||||||
|
throw new Error("active session");
|
||||||
|
}
|
||||||
|
|
||||||
|
// create call
|
||||||
|
const call = await addCall(access.current, cardId);
|
||||||
|
const { callId, keepAlive, callerToken, calleeToken } = call;
|
||||||
|
const aliveInterval = setInterval(async () => {
|
||||||
|
try {
|
||||||
|
await keepCall(access.current, call.callId);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
}, keepAlive * 1000);
|
||||||
|
let index = 0;
|
||||||
|
const ringInterval = setInterval(async () => {
|
||||||
|
try {
|
||||||
|
await addContactRing(contactNode, contactToken, { index, callId, calleeToken });
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
}, 3000);
|
||||||
|
calling.current = { state: "connecting", callId, host: true };
|
||||||
|
updateState({ callStatus: "connecting" });
|
||||||
|
const protocol = window.location.protocol === 'http:' ? 'ws://' : 'wss://';
|
||||||
|
ws.current = createWebsocket(`${protocol}${window.location.host}/signal`);
|
||||||
|
ws.current.onmessage = (ev) => {
|
||||||
|
// handle messages [polite]
|
||||||
|
// on connected stop ringing
|
||||||
|
console.log(ev);
|
||||||
|
}
|
||||||
|
ws.current.onclose = (e) => {
|
||||||
|
clearInterval(ringInterval);
|
||||||
|
clearInterval(aliveInterval);
|
||||||
|
calling.current = null;
|
||||||
|
updateState({ callStatus: null });
|
||||||
|
}
|
||||||
|
ws.current.onopen = () => {
|
||||||
|
calling.current.state = "ringing";
|
||||||
|
updateState({ callStatus: "ringing" });
|
||||||
|
ws.current.send(JSON.stringify({ AppToken: callerToken }))
|
||||||
|
}
|
||||||
|
ws.current.error = (e) => {
|
||||||
|
console.log(e)
|
||||||
|
ws.current.close();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { useContext, useState, useEffect } from 'react';
|
import { useContext, useState, useEffect } from 'react';
|
||||||
import { CardContext } from 'context/CardContext';
|
import { CardContext } from 'context/CardContext';
|
||||||
|
import { RingContext } from 'context/RingContext';
|
||||||
import { ViewportContext } from 'context/ViewportContext';
|
import { ViewportContext } from 'context/ViewportContext';
|
||||||
import { getListingMessage } from 'api/getListingMessage';
|
import { getListingMessage } from 'api/getListingMessage';
|
||||||
import { getCardByGuid } from 'context/cardUtil';
|
import { getCardByGuid } from 'context/cardUtil';
|
||||||
@ -21,6 +22,7 @@ export function useContact(guid, listing, close) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const card = useContext(CardContext);
|
const card = useContext(CardContext);
|
||||||
|
const ring = useContext(RingContext);
|
||||||
const viewport = useContext(ViewportContext);
|
const viewport = useContext(ViewportContext);
|
||||||
|
|
||||||
const updateState = (value) => {
|
const updateState = (value) => {
|
||||||
@ -157,12 +159,12 @@ export function useContact(guid, listing, close) {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
ring: async () => {
|
ring: async () => {
|
||||||
console.log("ringing!!");
|
console.log("calling!!");
|
||||||
const contact = card.state.cards.get(state.cardId);
|
const contact = card.state.cards.get(state.cardId);
|
||||||
const { node, guid } = contact.data.cardProfile;
|
const { node, guid } = contact.data.cardProfile;
|
||||||
const { token } = contact.data.cardDetail;
|
const { token } = contact.data.cardDetail;
|
||||||
await addContactRing(node, `${guid}.${token}`, { index: 0, callId: 'abc', calleeToken: '123' });
|
await ring.actions.call(state.cardId, node, `${guid}.${token}`);
|
||||||
console.log(contact);
|
//await addContactRing(node, `${guid}.${token}`, { index: 0, callId: 'abc', calleeToken: '123' });
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user