⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vojxtacallcontrol.java

📁 Myjxta的源代码 基于JXTA的P2P即时通信系统
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
        }        if (receiveTimeoutThread != null) {            receiveTimeoutThread.stopThread();        }        if (micControl != null) {            micControl.endMic();            micControl.releaseHardware();        }        if (speakerControl != null) {            speakerControl.endSpeaker();            speakerControl.releaseHardware();        }    }    /**     * Called from UI signaling user accepts call invitation     */    public void viewActionAcceptCall() {        if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) {            LOG.info("viewActionAcceptCall");        }        sendCommand(this.COMMAND_VOJXTA_INVITE_ACCEPT, null);        setProtocolState(this.SESSION_VOJXTA_INVITE_ACCEPT_SENT);    }    /**     * Called from IU signaling user wishes to place call on hold.     */    public void viewActionHoldCall() {        if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) {            LOG.info("viewActionHoldCall");        }        sendCommand(this.COMMAND_VOJXTA_HOLD_REQUEST, this.COMMAND_VOJXTA_HOLD_ACCEPT);        setProtocolState(this.SESSION_VOJXTA_HOLD_REQUEST_SENT);    }    /**     * Called from IU signaling user wishes to hangup call.     */    public void viewActionHangupCall() {        if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) {            LOG.info("viewActionHangupCall");        }        sendCommand(this.COMMAND_VOJXTA_HANGUP_REQUEST, this.COMMAND_VOJXTA_HANGUP_ACCEPT);        setProtocolState(this.SESSION_VOJXTA_HANGUP_REQUEST_SENT);        setCallEndTime();        micControl.endMic();        micControl.releaseHardware();        speakerControl.endSpeaker();        speakerControl.releaseHardware();    }    /**     * Called from IU signaling user wishes to resume a call previsously placed     * on hold.     */    public void viewActionResumeCall() {        if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) {            LOG.info("viewActionResumeCall");        }        sendCommand(this.COMMAND_VOJXTA_RESUME_REQUEST, this.COMMAND_VOJXTA_RESUME_ACCEPT);        setProtocolState(this.SESSION_VOJXTA_RESUME_REQUEST_SENT);    }    private void sendCommand(String command, String ackCommand) {        sendCommand(command, ackCommand, null);    }    /**     * Sends a command on the vojxta dialog pipe. This does not change the     * Protocol state. We have to remember to do this ourselves.     */    private void sendCommand(String command, String ackCommand, HashMap elementMap) {        if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) {            LOG.info("sendCommand : " + command);        }        DialogMessage msg = (DialogMessage) templateMessage.clone();        StringMessageElement commandElement = new StringMessageElement(                TAG_SESSION_COMMAND, command, null);        msg.addMessageElement(TAG_SESSION_COMMAND, commandElement);        if (elementMap != null) {            Iterator keys = elementMap.keySet().iterator();            while (keys.hasNext()) {                String elementName = (String) keys.next();                MessageElement element = (MessageElement) elementMap.get(elementName);                msg.addMessageElement(elementName, element);                LOG.info("added element " + elementName);            }        }        if (ackCommand != null) {            this.messageAckThread = new MessageAckThread(ackCommand);            this.messageAckThread.start();        }        this.vojxtaDialog.dispatch(msg);    }    /**     * Session state was meant for the UI as a messaging signaler to users     */    private void setSessionState(int sessionState) {        this.sessionState = sessionState;        this.vojxtaView.sessionStateChanged(this.sessionState);    }    /**     * Returns the current session state     */    public int getSessionState() {        return this.sessionState;    }    /**     * This method updates the current protocol state. Also signals the UI     * of a protocol state change.     */    private void setProtocolState(int protocolState) {        this.protocolState = protocolState;        if (this.protocolState == this.SESSION_VOJXTA_INVITE_REQUEST_SENT ||                this.protocolState == this.SESSION_VOJXTA_INVITE_REQUEST_RECEIVED) {            setSessionState(this.SESSION_VOJXTA_CONNECTING);        } else if (this.protocolState == this.SESSION_VOJXTA_INVITE_ACCEPT_SENT ||                this.protocolState == this.SESSION_VOJXTA_INVITE_ACCEPT_RECEIVED) {            setSessionState(this.SESSION_VOJXTA_CONNECTED);        } else if (this.protocolState == this.SESSION_VOJXTA_START_REQUEST_SENT ||                this.protocolState == this.SESSION_VOJXTA_START_REQUEST_RECEIVED) {            setSessionState(this.SESSION_VOJXTA_STARTING);        } else if (this.protocolState == this.SESSION_VOJXTA_START_ACCEPT_SENT ||                this.protocolState == this.SESSION_VOJXTA_START_ACCEPT_RECEIVED) {            setSessionState(this.SESSION_VOJXTA_STARTED);        } else if (this.protocolState == this.SESSION_VOJXTA_HOLD_ACCEPT_SENT ||                this.protocolState == this.SESSION_VOJXTA_HOLD_ACCEPT_RECEIVED) {            setSessionState(this.SESSION_VOJXTA_HOLDING);        } else if (this.protocolState == this.SESSION_VOJXTA_INCALL) {            setSessionState(this.SESSION_VOJXTA_INCALL);        } else if (this.protocolState == this.SESSION_VOJXTA_RESUME_ACCEPT_SENT ||                this.protocolState == this.SESSION_VOJXTA_RESUME_ACCEPT_RECEIVED) {            setSessionState(this.SESSION_VOJXTA_INCALL);        } else if (this.protocolState == this.SESSION_VOJXTA_HANGUP_REQUEST_SENT ||                this.protocolState == this.SESSION_VOJXTA_HANGUP_REQUEST_RECEIVED) {            setSessionState(this.SESSION_VOJXTA_ENDING);        } else if (this.protocolState == this.SESSION_VOJXTA_HANGUP_ACCEPT_SENT ||                this.protocolState == this.SESSION_VOJXTA_HANGUP_ACCEPT_RECEIVED) {            setSessionState(this.SESSION_VOJXTA_ENDED);        } else if (this.protocolState == this.SESSION_VOJXTA_DISCONNECT_REQUEST_SENT ||                this.protocolState == this.SESSION_VOJXTA_DISCONNECT_REQUEST_RECEIVED) {            setSessionState(this.SESSION_VOJXTA_DISCONNECTING);        } else if (this.protocolState == this.SESSION_VOJXTA_DISCONNECT_ACCEPT_SENT ||                this.protocolState == this.SESSION_VOJXTA_DISCONNECT_ACCEPT_RECEIVED) {            setSessionState(this.SESSION_VOJXTA_DISCONNECTED);        }        if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) {            LOG.info("ProtocolStateChanged to " + protocolState);        }        this.vojxtaView.protocolStateChanged(protocolState);    }    /**     * Returns the protocol state     */    public int getProtocolState() {        return this.protocolState;    }    /**     * Returns the current time in milliseconds to wait for a message respose     * before session shutdown.     */    public long getMessageAckTimeout() {        return (messageAckTimeout > this.MINIMUM_MESSAGE_ACK_TIMEOUT) ?                messageAckTimeout : DEFAULT_MESSAGE_ACK_TIMEOUT;    }    public void setMessageAckTimeout(long timeInMilliseconds) {        if (timeInMilliseconds > MINIMUM_MESSAGE_ACK_TIMEOUT) {            this.messageAckTimeout = timeInMilliseconds;        }    }    /**     * Message ack thread has timed out and no message ack has been received.     * End session.     */    protected void localActionMessageGoneUnAcknowledged() {        if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) {            LOG.info(" localActionMessageGoneUnAcknowledged ");        }        localActionEndSession();        /** Normally we'd just call sendcommand(END_SESSION) and wait for a         *  end END_SEESION_ACCEPT then go down gracefully. Since we aren't         *  receiving command messages we choose to just exit hard. */        /*         DialogMessage msg = (DialogMessage)templateMessage.clone ();                 StringMessageElement commandElement = new StringMessageElement (                TAG_SESSION_COMMAND, this.COMMAND_VOJXTA_DISCONNECT_REQUEST, null);                 msg.addMessageElement (TAG_SESSION_COMMAND, commandElement);                 this.vojxtaDialog.dispatch (msg);         **/        sendCommand(this.COMMAND_VOJXTA_DISCONNECT_REQUEST, null);        this.setProtocolState(this.SESSION_VOJXTA_DISCONNECTED);    }    /**     * After a message is sent this thread is instantiated, started and will     * wait till it's lock is notified of an incoming message or till a timeout     * is reached. The idea being each commmand message dispatched will return     * an accept response. If that response is received then +1 if not this thread     * will notify us and shutdown the session as gracefully as possible. A new     * Thread is started for each command message sent.     * TODO     * Better option then creating a new thread for each command. Reuse of a single     * thread maybe.     */    class MessageAckThread extends Thread {        private AckWaitLock ackWaitLock = null;        private String commandName = null;        private boolean threadEnded = false;        public MessageAckThread(String commandName) {            if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) {                LOG.info("MessageAckThread waiting for command " + commandName);            }            ackWaitLock = new AckWaitLock();            this.commandName = commandName;            this.setPriority(Thread.MIN_PRIORITY);            //this.setDaemon (true);        }        public void run() {            if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) {                LOG.info("MessageAckThread : Run ");            }            try {                synchronized (ackWaitLock) {                    ackWaitLock.wait(getMessageAckTimeout());                }            } catch (InterruptedException ix) {                ix.printStackTrace();            }            synchronized (ackWaitLock) {                if (!ackWaitLock.isAcknowledged()) {                    if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) {                        LOG.info("MessageAckThread : " + this.commandName +                                " command NOT acknowledged");                    }                    VoJxtaCallControl.this.localActionMessageGoneUnAcknowledged();                }            }            this.threadEnded = true;        }        /**         * Avoids a race condition... needs to be reworked.         */        public boolean isThreadEnded() {            while (!this.threadEnded) {                try {                    Thread.sleep(100);                } catch (InterruptedException ix) {                    ix.printStackTrace();                }            }            return this.threadEnded;        }        /**         * A message was received and this thread is alerted.         */        public void setMessageAcknowledged(String commandName) {            synchronized (ackWaitLock) {                if (this.commandName.equals(commandName)) {                    if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) {                        LOG.info("MessageAckThread : Received RIGHT Ack " +                                commandName + " for " + this.commandName +                                " : Command Ack");                    }                    ackWaitLock.setAcknowledged(true);                } else {                    if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) {                        LOG.info("MessageAckThread : Received WRONG Ack " +                                commandName + " for " + this.commandName +                                " : Command Ack");                    }                }                ackWaitLock.notify();            }        }        class AckWaitLock extends Object {            private boolean acknowledged = false;            public boolean isAcknowledged() {                return acknowledged;            }            public void setAcknowledged(boolean acknowledged) {                this.acknowledged = acknowledged;                if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) {                    LOG.info("AckWaitLock : SetAcknowldge " + acknowledged);                }            }        }    }    /**     * Because we push the voice payload through without periodic ack's we need     * a thread to count a timeout in case the other side goes down.  Time out     * of 40 seconds while IN CALL should be enough for any relay to catch up.     * A more elegant solution is needed though i'd still like to keep it simple.     * With reliable pipes SIP type acks seem too much     */    class ReceivedMessageTimeoutThread extends Thread {        public static final int SLEEP_TIME = 1000;        public static final long DEFAULT_PAYLOAD_MESSAGE_TIMEOUT = 1000 * 40;        public static final long MINIMUM_PAYLOAD_MESSAGE_TIMEOUT = 1000 * 40;        private long payloadMessageTimeout = DEFAULT_PAYLOAD_MESSAGE_TIMEOUT;        private boolean run = true;        public ReceivedMessageTimeoutThread() {            setPriority(Thread.MIN_PRIORITY);            //this.setDaemon (true);        }        public long getPayloadMessageTimeout() {            return payloadMessageTimeout;        }        public void setPayloadMessageTimeout(long payloadMessageTimeout) {            if (payloadMessageTimeout >= MINIMUM_PAYLOAD_MESSAGE_TIMEOUT) {                this.payloadMessageTimeout = payloadMessageTimeout;            }        }        public void stopThread() {            run = false;        }        public void run() {            while (run) {                try {                    Thread.sleep(VoJxtaCallControl.SECOND);                } catch (InterruptedException ix) {                    ix.printStackTrace();                }                if (getProtocolState() == VoJxtaCallControl.SESSION_VOJXTA_HOLDING) {                    continue;                }                long lastMessageReceived = 0;                if (speakerControl != null) {                    lastMessageReceived = speakerControl.getTimeOfLastVoiceMessage();                }                long currentTime = System.currentTimeMillis();                if (getProtocolState() == VoJxtaCallControl.SESSION_VOJXTA_INCALL &&                        (currentTime - lastMessageReceived) > getPayloadMessageTimeout()) {                    if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) {                        LOG.info(" diff " + (currentTime - lastMessageReceived) +                                " > " + getPayloadMessageTimeout());                    }                    VoJxtaCallControl.this.localActionMessageGoneUnAcknowledged();                }            }        }    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -