1

ここにある textclient と一緒に、SIP サーブレット チャット サーバーを動作させようとしています。

2 つのクライアントを使用して相互にメッセージを送信すると (ピアツーピア)、すべてがうまくいきます。しかし、1 つまたは複数のクライアントをサーバーと一緒に使用すると、サーバーがdoMessage()メソッド内の新しいメッセージを取得するまで、正確に 32 秒待たなければなりません。SIP サーバーとして Sailfin と一緒に Netbeans を使用しています。私が見ているSailfinのリクエストまたはレスポンスの間に、何らかの制限または構成可能な遅延またはタイムアウトがありますか?

必要に応じて、サーバー コードを投稿できます。

ありがとう

4

3 に答える 3

2

これがサーバーのコードです。後でwiresharkトレースを作成してみます。

public class ChatroomSipServlet extends SipServlet {

    public final static String USER_LIST = "userList";

    public final static String CHATROOM_SERVER_NAME = "chatroomservername";

    public String serverAddress;
    public SipFactory factory;

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        super.init(servletConfig);
        System.out.println("Chatroom sip servlet is gestart!");
        try {
            factory = (SipFactory) getServletContext().getAttribute("javax.servlet.sip.SipFactory");
            System.out.println("Sip Factory: " + factory);
        } catch (Exception e) {
            throw new ServletException("Factory probleem!", e);
        }
        getServletContext().setAttribute(USER_LIST, new ArrayList<String>());
        serverAddress = getServletConfig().getInitParameter(CHATROOM_SERVER_NAME);
        System.out.println("serverAddress is: " + serverAddress);
    }

    @Override
    public void destroy() {
        try {
            sendToAll(serverAddress, "Server sluit af!");
        } catch (Throwable e) {

            e.printStackTrace();
        }
        super.destroy();
    }

    protected void doMessage(SipServletRequest request) throws ServletException, IOException {

        System.out.println(getDateTime() + " Bericht ontvangen");

        request.createResponse(SipServletResponse.SC_OK).send();

        String message = request.getContent().toString();
        String from = ((SipURI) request.getFrom().getURI()).toString();

        if (message.equalsIgnoreCase("/quit")) {
            sendToUser(from, "Bye");
            removeUser(from);
            return;
        }

        if (!containsUser(from)) {
            sendToUser(from, "Welkom in de chatroom. Typ '/quit' om af te sluiten.");
            addUser(from);
        }

        if (message.equalsIgnoreCase("/who")) {
            String users = "Lijst van de gebruikers:\n";
            List<String> list = (List<String>) getServletContext().getAttribute(USER_LIST);
            for (String user : list) {
                users += user + "\n";
            }
            sendToUser(from, users);
            return;
        }

        if (message.equalsIgnoreCase("/join")) {
            return;
        }

        sendToAll(from, message);
    }

    protected void doErrorResponse(SipServletResponse response) throws ServletException, IOException {

//      String receiver = response.getTo().toString();
        String receiver = ((SipURI) response.getTo().getURI()).toString();
        System.out.println(getDateTime() + " Errorresponse voor " + receiver);
        removeUser(receiver);
    }

    protected void doSuccessResponse(SipServletResponse response) throws ServletException, IOException {

        response.getApplicationSession().invalidate();
    }

    private void sendToAll(String from, String message) throws ServletParseException, IOException {

        List<String> list = (List<String>) getServletContext().getAttribute(USER_LIST);
        for (String user : list) {
            SipApplicationSession session = factory.createApplicationSession();
            System.out.println(getDateTime() + " Session created voor " + user);
            SipServletRequest request = factory.createRequest(session, "MESSAGE", serverAddress, user);
            String msg = from + " stuurt: \n" + message;
            request.setContent(msg.getBytes(), "text/plain");
            request.send();
        }
    }

    private void sendToUser(String to, String message) throws ServletParseException, IOException {

        SipApplicationSession session = factory.createApplicationSession();
        SipServletRequest request = factory.createRequest(session, "MESSAGE", serverAddress, to);
        request.setContent(message.getBytes(), "text/plain");
        request.send();
    }

    private boolean containsUser(String from) {
        List<String> list = (List<String>) getServletContext().getAttribute(USER_LIST);
        return list.contains(from);
    }

    private void addUser(String from) {
        List<String> list = (List<String>) getServletContext().getAttribute(USER_LIST);
        list.add(from);
    }

    private void removeUser(String from) {
        System.out.println(getDateTime() + " " + from + " wordt verwijderd uit de lijst.");
        List<String> list = (List<String>) getServletContext().getAttribute(USER_LIST);
        list.remove(from);

    }

    @Override
    protected void doRegister(SipServletRequest req) throws ServletException, IOException {
        System.out.println("Register request ontvangen: " + req.getTo());
        int response = SipServletResponse.SC_OK;
        SipServletResponse resp = req.createResponse(response);
        resp.send();
    }

    private String getDateTime() {
        DateFormat dateFormat = new SimpleDateFormat("[" + "HH:mm:ss" + "]");
        Date date = new Date();
        return dateFormat.format(date);
    }
}

そしてsip.xml

<sip-app>
    <app-name>sip.chatvoorbeeld.ChatServer</app-name>
    <display-name>Chatroom Sip Servlet</display-name>
    <description>Chatroom Sip Servlet</description>

    <servlet-selection>
        <main-servlet>
            ChatroomSipServlet
        </main-servlet>
    </servlet-selection>
    <session-config>
        <session-timeout>5</session-timeout>
    </session-config>

    <servlet>
        <servlet-name>ChatroomSipServlet</servlet-name>
        <display-name>ChatroomSipServlet</display-name>
        <description>Chatroom SIP servlet</description>
        <servlet-class>
            sip.chatvoorbeeld.ChatroomSipServlet
        </servlet-class>
        <init-param>
            <param-name>chatroomservername</param-name>
            <param-value>sip:chatserver@192.168.56.1:5060</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
</sip-app>

doMessage()また、 「受信したメッセージ」を出力するだけのメソッドを使用して、空のサーブレットも試しました。同じ 32 秒の遅延...

Wireshark は私に与えます:

メッセージ「テスト」をサーバーに送信します。

MESSAGE sip:chatserver@192.168.56.1:5060;transport=udp SIP/2.0
Call-ID: aba00c2646a9b4e6df3b15df19dbf58d@192.168.56.101
CSeq: 1 MESSAGE
From: "bobby" <sip:bobby@192.168.56.101:5095>;tag=textclientv1.0
To: "chatserver" <sip:chatserver@192.168.56.1:5060>
Via: SIP/2.0/UDP 192.168.56.101:5095;branch=branch1
Max-Forwards: 70
Contact: "bobby" <sip:bobby@192.168.56.101:5095>
Content-Type: text/plain
Content-Length: 4

test

サーバーが返信します:

SIP/2.0 200 OK
Content-Length: 0
To: "chatserver"<sip:chatserver@192.168.56.1:5060>;tag=g9vdns7u-e
Cseq: 1 MESSAGE
Via: SIP/2.0/UDP 192.168.56.101:5095;branch=branch1
From: "bobby"<sip:bobby@192.168.56.101:5095>;tag=textclientv1.0
Call-Id: aba00c2646a9b4e6df3b15df19dbf58d@192.168.56.101
Server: Glassfish_SIP_2.0.0

MESSAGE sip:bobby@192.168.56.101:5095 SIP/2.0
Max-Forwards: 69
Content-Length: 43
To: <sip:bobby@192.168.56.101:5095>
Cseq: 1 MESSAGE
Via: SIP/2.0/UDP 192.168.56.1:5060;branch=z9hG4bKdaacb7673c871796474ca951221a6643db6c
Content-Type: text/plain
Call-Id: 192.168.56.1_11_6595680936174578736
From: <sip:chatserver@192.168.56.1:5060>;tag=g9vdns7u-g

sip:bobby@192.168.56.101:5095 stuurt: 
test

その後、クライアントは再び OK で応答します。

SIP/2.0 200 OK
To: <sip:bobby@192.168.56.101:5095>;tag=888
CSeq: 1 MESSAGE
Via: SIP/2.0/UDP 192.168.56.1:5060;branch=z9hG4bKdaacb7673c871796474ca951221a6643db6c;received=192.168.56.1
Call-ID: 192.168.56.1_11_6595680936174578736
From: <sip:chatserver@192.168.56.1:5060>;tag=g9vdns7u-g
Content-Length: 0

これまでのところ、すべてがうまく機能しています。しかし、サーバー「test2」に2番目のメッセージを送信すると、次のようになります。

クライアントからサーバーへ:

MESSAGE sip:chatserver@192.168.56.1:5060;transport=udp SIP/2.0
Call-ID: 95ad65365378b9b6b5bd7ad3629f7b02@192.168.56.101
CSeq: 1 MESSAGE
From: "bobby" <sip:bobby@192.168.56.101:5095>;tag=textclientv1.0
To: "chatserver" <sip:chatserver@192.168.56.1:5060>
Via: SIP/2.0/UDP 192.168.56.101:5095;branch=branch1
Max-Forwards: 70
Contact: "bobby" <sip:bobby@192.168.56.101:5095>
Content-Type: text/plain
Content-Length: 5

test2

その後、サーバーは次のように応答します。

SIP/2.0 200 OK
Content-Length: 0
To: "chatserver"<sip:chatserver@192.168.56.1:5060>;tag=g9vdns7u-e
Cseq: 1 MESSAGE
Via: SIP/2.0/UDP 192.168.56.101:5095;branch=branch1
From: "bobby"<sip:bobby@192.168.56.101:5095>;tag=textclientv1.0
Call-Id: aba00c2646a9b4e6df3b15df19dbf58d@192.168.56.101
Server: Glassfish_SIP_2.0.0

しかし、その後、通信が停止します... 200 OK が返されますがprintln()doMessage()メソッドが渡されません。

于 2010-05-31T10:06:38.267 に答える
1

32秒は、トランザクションの通常のタイムアウトです(RFC3261では64 * T1と示され、T1のデフォルトは500msです)。

タイムアウトがSailFinの設定ミスではない可能性が非常に高いことを除いて、私はあなたの問題の解決策を直接考えていません。したがって、wiresharkトレースとサーバーコードを提供してください。

于 2010-05-30T18:09:42.080 に答える
0

私自身の質問に答えるために、誰かが同じ問題に遭遇した場合、これは RFC 3261 の次のセクション 8.1.1.7 に対する textclient のバグであることがわかりました。

ブランチ パラメータ値は、UA によって送信されるすべての要求に対して、空間と時間全体で一意である必要があります。この規則の例外は、2xx 以外の応答に対する CANCEL と ACK です。以下で説明するように、CANCEL リクエストは、キャンセルするリクエストと同じブランチ パラメータの値を持ちます。セクション 17.1.1.3 で説明したように、2xx 以外の応答に対する ACK には、応答を確認する INVITE と同じブランチ ID も含まれます。

トランザクション ID としての使用を容易にするブランチ ID パラメータの一意性プロパティは、RFC 2543 の一部ではありませんでした。

この仕様に準拠する要素によって挿入されるブランチ ID は、常に文字「z9hG4bK」で始まる必要があります。

SipLayer.java の次の行

ViaHeader viaHeader = headerFactory.createViaHeader(getHost(),
getPort(), "udp", "branch1");

「branch1」パラメーターを使用してすべてのメッセージを作成します。このパラメーターを一意にすると、問題が修正されます。

于 2010-06-08T13:56:53.603 に答える