Как отправить мгновенное сообщение через SIP
У меня есть настольное приложение для Windows, сделанное моим провайдером мобильной сети, которое выполняет всевозможные действия с помощью SIP: вызов, отправка сообщения и т.д. Скриншот того, как это приложение успешно отправляет MESSAGE
(последние 4 строки):
![Wireshark]()
MESSAGE
запрос из настольного приложения отправляется как (4-я строка сзади):
MESSAGE sip:[email protected] SIP/2.0
Via: SIP/2.0/UDP LOCALIP:2112;branch=z9hG4bK-d8754z-905183245f478c76-1---d8754z-;rport
Max-Forwards: 70
To: "TO"<sip:[email protected]>
From: "FROM"<sip:[email protected]>;tag=63088d09
Call-ID: NGVhMDJhYzQwNmExOTQyNThmNjc5OGNmOTViNDUyYWM.
CSeq: 2 MESSAGE
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO
Content-Type: text/plain
Content-Length: 4
test
и успешный ответ для этого:
SIP/2.0 407 Proxy Authentication Required
Via: SIP/2.0/UDP LOCALIP:2112;received=EXTERNALIP;branch=z9hG4bK-d8754z-905183245f478c76-1---d8754z-;rport=2112
To: "TO"<sip:[email protected]>;tag=c005f0e30133ec730add76fc91f4bea
From: "FROM"<sip:[email protected]>;tag=63088d09
Call-ID: NGVhMDJhYzQwNmExOTQyNThmNjc5OGNmOTViNDUyYWM.
CSeq: 2 MESSAGE
Content-Length: 0
Proxy-Authenticate: Digest nonce="3F178051B97E1F52000123000A3C53D4B",realm="DOMAIN",algorithm=MD5,qop="auth"
Затем я пытаюсь отправить идентичный (и n-варианты) запрос из PHP, но я всегда получаю SIP/2.0 403 Forbidden
вместо SIP/2.0 407 Proxy Authentication Required
:
SIP/2.0 403 Forbidden
Via: SIP/2.0/UDP LOCALIP;received=EXTERNALIP
To: "TO"<sip:[email protected]>;tag=aprqngfrt-f7ccjj0000020
From: "FROM"<sip:[email protected]>;tag=8f7be81d
Call-ID: [email protected]
CSeq: 1 MESSAGE
Reason: Q.850;cause=55;text="Call Terminated"
Content-Length: 0
Самое смешное, что если я отправлю запрос REGISTER
, он работает, и я успешно получаю заголовок SIP/2.0 401 Unauthorized
с WWW-Authenticate
. Я пересчитываю авторизацию и повторно отправляю ее. Затем я получаю SIP/2.0 200 OK
. Как это работает с MESSAGE
.
Что может быть неправильным? Что я упустил? Запрос MESSAGE
требует какого-либо другого запроса до этого (я уже пробовал REGISTER
раньше)?
Я прочитал RFC 3428 вверх и вниз, попробовал все возможные примеры, но безуспешно.
Ответы
Ответ 1
Если вы просмотрите полученный ответ 403, вы увидите заголовок Reason. Строка Q.850 в начале указывает, что это будет код причины, определяемый Рекомендацией МСЭ-Т.
В частности, приведенный код причины 55 связан с ISDN и литературными средствами "Входящие вызовы, запрещенные в пределах Закрытой группы пользователей" (вы можете проверить его в RFC 3398) и, как правило, означает, что в пределах группы участников вызов приема ограничен.
С другой стороны, причина 55 также указывает на проблему в запросе, особенно в отношении пользователя (отправителя или получателя). Следующая диаграмма показывает обычный обмен сообщениями между пользователями SIP:
A Server B
| REGISTER | |
|--------------->| |
| 200 OK | |
|<---------------| |
| | REGISTER |
| |<--------------|
| | 200 OK |
| |-------------->|
| MESSAGE | |
|--------------->| MESSAGE |
| |-------------->|
| | 200 OK |
| |<--------------|
| 200 OK | |
|<---------------| |
На самом деле, был строгим, REGISTER от пользователя A не требуется, но большинство систем (например, IMS) использует его как механизм аутентификации. Затем в запросе REGISTER специальные заголовки:
Contact: <sip:[email protected]_IP:LOCAL_PORT>
Expires: REGISTRATION_DURATION
Имейте в виду, что 200 OK отвечает на REGISTER, может содержать заголовок Expires:
или expires
внутри заголовка Contact:
, который указывает принятое время истечения срока действия. Например:
SIP/2.0 200 OK
...
Contact: <sip:[email protected]_IP:LOCAL_PORT>; expires=60
...
В этой ситуации вы должны повторно зарегистрироваться до истечения этого срока (60 секунд в примере).
Помня о том, что вы пытаетесь отправить SMS на мобильный телефон, точка приема напрямую управляется вашим сетевым провайдером MGCF, поэтому это оставляет регистрацию отправителя или запрос MESSAGE.
О вашем исходном предложении MESSAGE, запросить URI (первая строка сообщения), должно быть:
MESSAGE sip:[email protected] SIP/2.0
Потому что это относится к сущности приема MESSAGE.
Надеюсь, что это поможет.
Ответ 2
Как я уже сказал вам в комментариях, я не эксперт SIP, а мой друг. Я спросил его о вашем случае, и вот что он сказал мне:
Протокол SIP - это протокол диалога, означающий, что каждое сообщение представляет собой диалог с уникальным идентификатором диалога (что-то вроде идентификатора сеанса в HTTP). Разница между SIP и HTTP заключается в том, что идентификатор сеанса используется между различными соединениями TPC/IP (HTTP-запросы), в то время как идентификатор диалога используется в одном и том же соединении TPC/IP, но между различными сообщениями.
Мне кажется, что то, что вы пытаетесь сделать здесь, похоже на захват сеанса в HTTP. Хотя можно захватить идентификатор сеанса в HTTP и отправить его другому клиенту, то же самое не для SIP. Согласно моим друзьям, SIP-серверы имеют внутреннюю память, с которой идентификатор диалога принадлежит к тому соединению, и вы не можете пропустить ваши сообщения в чужой диалог, просто зная их идентификатор диалога.
В вашем вопросе не говорится, действительно ли это то, что вы пытаетесь сделать, но если это так, то я должен сказать, что вы не можете. Тот факт, что вы можете отправить команду REGISTER
, показывает, что ваша связь с сервером SIP выполнена. Все, что вам нужно сделать, это начать свой собственный диалог и взять его оттуда.