'2017/04/01'에 해당되는 글 2건

  1. 2017.04.01 [WebRTC] Janus-Gateway 에 대하여 - API 분석
반응형

 Janus-Gateway 는 HTTP Rest, WebSocket, RabbitMQ, MQTT, UnixSocket API를 제공한다. 각각 다른 API를 제공하는 것은 아니고, JSON 형태로 API를 제공하며 REST, WebSocket 등등은 이 JSON 값을 전달하기 위한 프로토콜이다.


 Janus-Gateway의 동작은 다음과 같은 순서로 동작한다.


1. session creation

  Janus-Gateway는 서비스(Plugin)을 이용하는 클라이언트를 세션으로 관리한다. 세션이 생성되면 이 세션으로 특정 plugin 을 이용하기 위한 요청을 보낼 수 있다. 세션으로 특정 plugin을 이용하기 위해서 생성된 것이 Handle_id 값이다. 이 handle_id 는 Janus-Gateway 와 Client간의 RTPPeerConnection을 관리하는 값이다. 즉 Plugin 에 하나의 PeerConnection이 생성되는 구조이며, 이 관리 값이 handle_id가 되는 것이다.

 특정 Session_ID 값으로 여러 Handle_ID를 생성할 수 있다. 클라이언트에서는 하나의 Session_ID를 생성하고 여러 종류의 Plugin을 이용해서 여러 RTPPeerConnection을 생성할 수 있는 것이다.

 이 세션값으로 keepalive 메시지를 보내며, 세션을 생성한 socket과 바인드 되어 있어서 API를 호출한 socket이 종료되면 해당 세션 그리고 여기에 attach 된 plugin들의 핸들도 사라진다.


 Janus-Gateway와 연동되는 기본 API들은 모두 TransactionID를 설정해서 보내야 한다. 이는 Janus-Gateway가 비동기적으로 동작하기 때문에 이 Transaction 으로 응답을 구별하기 위함이다. 다음은 Transaction을 생성하는 Javascript 코드이다.

function getTrxId() {

        var len=12;

        var charSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

        var randomString = '';

        for (var i = 0; i < len; i++) {

                var randomPoz = Math.floor(Math.random() * charSet.length);

                randomString += charSet.substring(randomPoz,randomPoz+1);

        }

        return randomString;

}; 


그리고 janus 라는 기본 명령어 필드가 존재하는데, session을 생성하는 명령은 "create" 이다.

 다음은 Session 을 생성하는 Javascript 코드이다. (ws 는 websocket 연결을 가정한다.)

const janus={};

janus.send_create_session=(ws)=>{

        let trxid=getTrxId();

        let request = { 

                "janus": "create", 

                "transaction": trxid

        };

        ws.send(JSON.stringify(request));

        return trxid;

}; 

 다음은 요청-응답의 예이다.

요청>

 {"janus":"create","transaction":"TYuHYuCxLKid"}

응답>

{"janus":"success","transaction":"TYuHYuCxLKid","data":{"id":1078166167654140}}

 응답의 data.id 가 session_id가 된다.

 

2. session destroy

 다음은 세션을 파괴하는 명령에 대한 코드이다. 이 세션에 연결된 핸들들도 같이 삭제된다.

janus.send_destroy_session=(ws,session_id)=>{

        let trxid=getTrxId();

        let request={

                janus:"destroy",

                transaction:trxid,

                session_id:session_id

        };      

        ws.send(JSON.stringify(request);

};

 다음은 요청-응답의 예이다.

 요청>

{"janus":"destroy","transaction":"Ut2czjYHuAJe","session_id":5396131839672173}

 응답>

{"janus":"success","session_id":5396131839672173,"transaction":"Ut2czjYHuAJe"}



3. attach plugin (handle creation)

 다음은 특정 plugin에 session을 attach 하는 코드이다.

janus.send_attach_plugin=(ws,opaqueId,session_id,plugin_name)=>{

        let trxid=getTrxId();

        let request = {

                "janus": "attach",

                "transaction": trxid,

                "opaqueId": opaqueId,

                "session_id": session_id,

                "plugin":"janus.plugin.streaming"

        };

        console.log("attach_plugin_msg:"+JSON.stringify(request));

        ws.send(JSON.stringify(request));

        return trxid;

};

 opaqueId 는 handle을 Application 입장에서 사용하기 위함인데, 예를 들어 여러 session을 가진 특정 사용자를 구별하기 위해서 사용하거나, 같은 사용자의 handle 을 수집하기 위한 용도로 사용할 수 있다. janus-gateway에서는 내부적으로 이 값을 사용하지 않으며, admin api 를 통해서 핸들 정보를 조회하거나 handle event가 trigger 될 때 제공된다.

 다음은 janus.plugin.audiobridge plugin를 attach 하는 요청-응답의 예이다.

 요청> 

{"janus":"attach","transaction":"4uOOc9BEfqeb","opaqueId":"audiobridgetest-DpLzkETia8eX","session_id":4894477569154728,"plugin":"janus.plugin.streaming"}

 응답>

{"janus":"success","session_id":4894477569154728,"transaction":"4uOOc9BEfqeb","data":{"id":8858769173674836}}

 응답의 data.id 가 handle_id가 된다.


4. detach plugin

 특정 Plugin에 attach 된 handle을 해제한다. 다음은 그 코드이다.

janus.send_detach_plugin=(ws,session_id,handle_id)=>{

        let trxid=getTrxId();

        let request = { 

                "janus": "detach", 

                "transaction": trxid,

                "session_id": session_id,

                "handle_id":handle_id

        };      

        ws.send(JSON.stringify(request));

};

 요청-응답은 다음과 같다. 응답의 경우 janus:success 와 janus:detached, 두가지 응답이 온다. 

요청>

{"janus":"detach","transaction":"AEzv9SsxLLZM","session_id":3486958638653612,"handle_id":6541525317175383}

 응답>

{"janus":"detached","session_id":3486958638653612,"sender":6541525317175383}

{"janus":"success","session_id":3486958638653612,"transaction":"AEzv9SsxLLZM"}



5. plugin command

 plugin의 command는 plugin의 종류에 따라 다르다. plugin command는 janus 웹 사이트에 정리되어 있지 않으며 plugin 소스 코드 또는 demo web page 코드를 보고 분석해야 한다. 향후 다른 포스팅에서 janus.plugin.audiobridge 와 janus.plugin.streaming에 대한 command를 분석해 보도록 하겠다.


6. tricle

 tricle은 client에서 발생하는 ice candidate를 전송하는 API 이다. tricle 은 plugin 에 따라서 offer/answer 가 발생하고 난 다음 client에서 ice candidate가 발생하면 tricle api로 해당 candidate를 전송한다. (비동기) 다음은 tricle 메시지를 보내는 코드이다.

janus.send_icecandidate=(ws,session_id,handle_id,candidate)=>{

        let trxid=getTrxId();

        let s_candidate={

                "candidate":candidate.candidate,

                "sdpMid":candidate.sdpMid,

                "sdpMLineIndex":candidate.sdpMLineIndex

        };      

        let request = { 

                "janus": "trickle", 

                "session_id":session_id,

                "handle_id":handle_id,  

                "candidate": s_candidate, 

                "transaction": trxid    

        };                      

        ws.send(JSON.stringify(request));

        return trxid;                   

}; 

 다음은 tricle에 대한 응답-요청이다.

 요청> 

{"janus":"trickle","session_id":2574473726807889,"handle_id":523990459844417,"candidate":{"candidate":"candidate:478132711 1 tcp 1518275327 2001::9d38:6abd:432:3f0d:2d86:4250 9 typ host tcptype active generation 0 ufrag YUP0 network-id 2 network-cost 50","sdpMid":"audio","sdpMLineIndex":0},"transaction":"6BUFmPJFp2Zx"}

  응답>

{"janus":"ack","session_id":2574473726807889,"transaction":"6BUFmPJFp2Zx"}


7. webrtc up event

 webrtc channel이 생성되면 janus-gateway로 부터 webrtcup event가 전달된다. 다음은 webrtcup event 예이다.

 {"janus":"webrtcup","session_id":2574473726807889,"sender":523990459844417}


8. media event

 webrtcup event가 전달되고 난 다음에 실제 media traffic이 발생하기 시작하면 media event가 전달된다. 다음은 그 예이다.

 {"janus":"media","session_id":2574473726807889,"sender":523990459844417,"type":"audio","receiving":true}


9. 기타 webrtc event

 webrtc 관련으로 slowlink 및 hangup event가 발생할 수 있다.

(https://janus.conf.meetecho.com/docs/rest.html 참고)


10. keepalive 

 janus-gateway에서는 특정 g 생성되면 해당 세션에 60초 이내어 어떤 activity 가 없을 경우 session은 종료된다. 세션을 유지하기 위하여 keepalive message를 janus-gateway로 전송한다. 다음은 관련 코드이다.

janus.send_keep_alive=(ws,session_id)=>{

        let trxid=getTrxId();

        let request={

                janus:"keepalive",

                session_id:session_id,

                transaction:trxid

        };

        ws.send(JSON.stringify(request));

        return trxid;

};

 다음은 요청-응답이다.

 {"janus":"keepalive","session_id":5485723921011822,"transaction":"QZ6Wa2PrEOYj"}

 {"janus":"ack","session_id":5485723921011822,"transaction":"QZ6Wa2PrEOYj"}


반응형
Posted by alias
,