つぶやきテック

日々のつぶやきアウトプット

つぶやきVoIP

VoIP

  • インターネットなどのIPネットワークを利用して通信しようとする技術です。
  • より細かくみると、電話交換で行われてきた呼制御と、音声をIPパケット化する技術で成り立っています

SIP (Session Initiation Protocol)

  • マイクロソフト社が開発した、呼制御に用いられるプロトコルです。
  • アプリケーションプロトコルの1つであり、HTTPと同じように、リクエスト・レスポンスというメッセージをやりとりすることで呼制御を行います。

SIPメッセージ

  • REGISTER:電話機の位置情報登録~>DNSのAレコードを登録するみたいな感じ
  • INVITE:端末を通話へ招待
  • ACK:確認応答
  • BYE:呼の解放

INVITEメッセージの実例は下のような感じです*1

INVITE sip:bob@tokyo.com SIP/2.0
------------------------------ヘッダここから--------------------------------------------
Via: SIP/2.0/UDP pc33.sapporo.com;branch=z9hG4bKnashds8 //リクエストが辿ったパス
Max-Forwards: 70
To: Bob <sip:bob@tokyo.com>
From: Alice <sip:alice@sapporo.com>;tag=1928301774
Call-ID: a84b4c76e66710@pc33.sapporo.com
CSeq: 314159 INVITE                             // トランザクション毎にインクリメントされる値
Contact: <sip:alice@pc33.sapporo.com>
Content-Type: application/sdp 
Content-Length: 142
------------------------------ヘッダここまで--------------------------------------------
------------------------------ボディここから--------------------------------------------
v=0                                                                                      // プロトコルのバージョン
o=alice 53655765 2353687637 IN IP4 pc33.sapporo.com // 発信元及びセッション識別子
s=-                                                                                      // セッション名
t=0 0                                                                                   // セッションがアクティブな時間
c=IN IP4 pc33.sapporo.com                                               // セッション情報
m=audio 3456 RTP/AVP 0                                                  // メディア名・伝送アドレス
a=rtpmap:0 PCMU/8000                                                    // 0行以上のメディア属性行
------------------------------ボディここまで--------------------------------------------

なお、NATを通す場合、ボディに記載してあるIP情報まで変換する機能を もったNAT機器でないと、通話セッションが生成できないという問題が発生します。

Django マイグレーション関連のコマンド&エラー

基本の操作

マイグレーションファイルを作成

$ python manage.py makemigartions

マイグレーションファイルをDBに適用

$ python manage.py migrate (MIGRATION_ID)

マイグレーションの一覧を表示

$ python manage.py showmigrations (MIGRATION_ID)

よく出会うエラー

整合性不正によるエラー

エラーメッセージ例:

django.db.utils.ProgrammingError: relation "sample_user" does not exist
LINE 1: ...user"."is_active", "sample_user"."date_joined" FROM "sample_user...

このようなエラーは、主にmigrationコマンドによるマイグレーションファイルの DBへの適用時に、その適用の順番が逆転していることが原因で発生します。

上の場合であれば、先に "sample_user" を明示的に指定して先にマイグレーション することで解消することが多いです。

# sample_userを先にマイグレーション
$ python manage.py migrate sample_user

# 残りをマイグレーション
$ python manage.py migrate

参考

つぶやきメモーLinuxコマンド篇【随時更新】

sed:テキストファイルをフィルター処理で編集

sedコマンドとは

  • "Stream EDitor"の略です。
  • 指定したファイルをコマンドに従って処理し、標準出力へ出力します。
  • ファイル名を省略した場合は、標準入力からのデータを処理します。

書式:

sed [option]
sed [option] (スクリプトコマンド) (入力ファイル)

sed の主なオプション

オプション 長いオプション 意味
-i --in-place ファイルを直接編集する
-e --expression=(スクリプト) スクリプト(コマンド)を追加する

env:環境変数を一時的に設定しコマンド実行

envコマンドとは

  • 環境変数に特定の値を指定して、後に続くコマンドを実行します。
env (環境変数名)=(値) (コマンド)

envの主なオプション

オプション 長いオプション 意味
-i --ignore-enviroment 環境変数が設定されていない状態でコマンド実行
-u (変数名) --unset=(変数名) 指定した環境変数が設定されていない状態でコマンド実行

curl:手軽にHTTPリクエスト

curlコマンドとは

  • 様々なプロトコルを使用して、データ転送を実行できます。
curl (リクエストURL)

curlの主なオプション

オプション 意味
-X リクエストメソッドの指定
-H ヘッダの変更
-d コンテンツの変更
-v 通信詳細の出力
-f 終了コード変更*1
-o レスポンスボディの出力先のパスを指定
-L リダイレクトを有効にする

使用例:

$ curl -v -H "content-type: application/json" -X POST -d'{"gohann":"suki", "oyatsu":"daisuki"}' http://sample.org/post

*   Trying xxx.xxx.xxx.xxx...
* TCP_NODELAY set
* Connected to sample.org (xxx.xxx.xxx.xxx) port xx (xx)
> POST /post HTTP/1.1
> Host: sample.org
> User-Agent: curl/7.64.1
> Accept: */*
> content-type: application/json
> Content-Length: 41
> 
* upload completely sent off: 41 out of 41 bytes
< HTTP/1.1 200 OK
< Date: Mon, 30 Mar 2020 xx:xx:xx GMT
< Content-Type: application/json
< Content-Length: 486
< Connection: keep-alive
< Server: xxxxxxxx/xxxxxxxx
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Credentials: true
< 
{
  "args": {}, 
  "data": "{\"gohann\":\"suki\", \"oyatsu\":\"daisuki\"}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Content-Length": "41", 
    "Content-Type": "application/json", 
    "Host": "sample.org", 
    "User-Agent": "curl/7.64.1", 
    "X-Amzn-Trace-Id": "Root=12345678901234567890"
  }, 
  "json": {
    "gohann": "suki", 
    "oyatsu": "daisuki"
  }, 
  "origin": "xxx.xxx.xxx.xxx", 
  "url": "http://sample.org/post"
}
* Connection #0 to host sample.org left intact
* Closing connection 0

*1:通常、curlはエラーになっても何食わぬ顔で正常終了します(終了コード0)。-fオプションをつけることで、異常終了時に終了コード22で終わるようになります。

django.db の InconsistentMigrationHistory例外に遭遇した時の対処

InconsistentMigrationHistoryとは?

  • DB内の依存関係が原因で、整合のとれたマイグレーションができなくなる 例外のよう。
  • エラーメッセージは、例えば以下のように表示されます。
django.db.migrations.exceptions.InconsistentMigrationHistory: 
Migration example_django.0001_initial is applied before its dependency sample_app.0001_initial on database 'default'.

どう対処しようか?

  • 私の場合は、settings.py の INSTALLED_APP を一時的に修正し、 マイグレーション実行後に元に戻す、という対処で解決できました。

settings.pyを一時修正

INSTALLED_APPS = [
    ...
    # 'example_django',  ←例外が発生した部分を一時的にコメントアウト
    ...
]

マイグレーションを実行

$ python manage.py makemigrations
$ python manage.py migrate

settings.py を復元

マイグレーションを再実施

  • これで整合がとれたマイグレーションができるようです。

  • 今回は こちらのサイトを参考にさせていただきました。

  • この対応でなぜ解決したのか、まだ「?」な部分も多いです。またわかったら追記していきたいと思います。