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

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の一致を確認 |
参考リンク
- https://sip2sip.info/ (公式サイト)
- https://sip2sip.info/signup (アカウント登録)
- https://sip2sip.info/features (機能一覧)
- https://sip2sip.info/help (ヘルプ・設定ガイド)
- https://docs.sipjs.com/ (SIP.js公式ドキュメント)

大阪のエンジニアが書いているブログ。
コメント