SIP.js実践ガイド React+TypeScriptで作るブラウザVoIPアプリ(sip2sip.info対応版)

sip.js JavaScript
この記事は約7分で読めます。

この記事の最終更新日: 2025年5月15日

sip.js

SIP.jsは、WebRTCとSIPプロトコルを組み合わせてブラウザ上で音声・映像通話を実現できるJavaScriptライブラリです。本記事では、無料Public SIPサービス「sip2sip.info」を利用し、初心者でも迷わない手順でVoIPアプリを開発する方法から、実運用で重要なポイントまで詳しく解説します。


1. 事前準備:動作確認に必要な環境

  • Node.js(推奨 v16以上)とnpmまたはyarn
  • HTTPS対応ローカルサーバー(自己署名証明書可)
  • モダンブラウザ(Chrome、Firefox、Edgeなど)
  • sip2sip.info 無料SIPアカウント
  • 443番ポート通信が可能なネットワーク設定

2. sip2sip.infoの特徴と登録方法

2.1 無料アカウント登録方法

  • sip2sip.info/signup にアクセス
  • ユーザー名、パスワード、氏名、メールアドレスを登録
  • メール認証不要、すぐに利用可能

2.2 サービスの主な特徴

  • 音声通話/ビデオ通話(SIP+RTP)
  • インスタントメッセージとファイル転送(MSRP)
  • プレゼンス通知(SIP SIMPLE+XCAP)
  • XMPPゲートウェイ連携
  • アドレス帳同期(XCAP・LDAP)
  • WebRTCベースの多者会議対応
  • 公衆電話網(PSTN)発信(有料クレジット制)
  • 商用利用、大量アカウント作成は禁止(個人利用のみ)

3. 通信ポートとネットワーク設定

  • SIPシグナリング:UDP/TCP 5060、TLS 5061(proxy.sipthor.net)
  • WebSocket(WSS)通信:443番ポート(webrtc.sipthor.net)
  • STUNサーバー:_stun._udp.sip2sip.info(UDP 3478)
  • TURNサーバー:UDP/TCP 3478, TLS 5349(自動提供)

※ sip2sip.infoではSTUN/TURNサーバは自動通知され、特別な設定なしにICEネゴシエーションが成立します。


4. プロジェクト作成と基本構成

mkdir sipjs-app
cd sipjs-app
npm init -y
npm install sip.js react react-dom
npm install --save-dev typescript @types/react @types/react-dom

ディレクトリ構成例

/sipjs-app
├ public/index.html
├ src/
│  ├ index.tsx
│  ├ App.tsx
│  └ sip/ua.ts
├ tsconfig.json
└ package.json


5. UserAgent作成モジュール

// src/sip/ua.ts
import { UserAgent } from "sip.js";

export function createUA(user: string, pass: string): UserAgent {
  const uri = UserAgent.makeURI(`sip:${user}@sip2sip.info`)!;
  return new UserAgent({
    uri,
    transportOptions: { server: "wss://sip2sip.info/ws" },
    authorizationUsername: user,
    authorizationPassword: pass,
    logLevel: "info"
  });
}


6. React+TypeScriptで通話機能を実装

// src/App.tsx
import React, { useEffect, useRef, useState } from "react";
import { createUA } from "./sip/ua";
import { SessionState } from "sip.js";

const App: React.FC = () => {
  const [ua, setUA] = useState<any>();
  const [session, setSession] = useState<any>();
  const audioRef = useRef<HTMLAudioElement>(null);

  useEffect(() => {
    const userAgent = createUA("yourUser", "yourPass");
    userAgent.start();
    userAgent.delegate.onInvite = invitation => {
      invitation.accept().then(() => {
        setSession(invitation);
        audioRef.current!.srcObject = invitation.sessionDescriptionHandler.remoteStream;
      });
    };
    setUA(userAgent);
    return () => userAgent.stop();
  }, []);

  const call = () => {
    navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => {
      const inviter = ua!.invite("sip:callee@sip2sip.info", {
        sessionDescriptionHandlerOptions: { constraints: { audio: true } },
        sessionDescriptionHandlerFactoryOptions: { localMedia: { stream } }
      });
      setSession(inviter);
      inviter.stateChange.addListener(state => {
        if (state === SessionState.Established) {
          audioRef.current!.srcObject = inviter.sessionDescriptionHandler.remoteStream;
        }
      });
    });
  };

  const hangup = () => session?.bye();

  return (
    <div>
      <h1>ブラウザVoIPデモ</h1>
      <button onClick={call} disabled={!!session}>発信</button>
      <button onClick={hangup} disabled={!session}>切断</button>
      <audio ref={audioRef} autoPlay />
    </div>
  );
};

export default App;


7. 運用時の注意点と推奨設定

  • WSS使用推奨:WebSocketは443番(WSS)を使用
  • ICE候補優先設定:STUN→TURN(必要時)
  • PSTN通話は有料:PSTN発信は別途クレジット購入が必要
  • 着信時の自動Acceptは危険:本番では確認画面を挟む
  • スパム防止対策:エラーハンドリング強化+rate limit実装

8. トラブルシューティングまとめ

問題解決方法
WSS接続エラーサーバー証明書確認、443番ポート開放
音声が届かないSTUN/TURN設定確認、ブラウザ権限設定
ICE失敗ファイアウォール/NAT設定と回線状態を確認
着信通知がない登録URIとINVITE先URIの一致を確認

参考リンク

コメント

タイトルとURLをコピーしました