📄 vijxtacallcontrol.java
字号:
} /** * Returns the current time in milliseconds to wait for a message respose * before session shutdown. */ public long getMessageAckTimeout() { return (messageAckTimeout > 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. */ sendCommand(COMMAND_VIJXTA_DISCONNECT_REQUEST); this.setProtocolState(SESSION_VIJXTA_DISCONNECTED); } /** * */ public RemoteMonitorControl getRemoteMonitorControl() { return this.remoteMonitorControl; } /** * */ public DeviceMonitorControl getLocalMonitorControl() { return this.localMonitorControl; } /** * A templete DialogMessage is already constructed. All we need do is call * this method and clone. This will cleanup the code for message production * as well offer the possibility of a speedup in message creation. * * @return templeted DialogMessage */ public DialogMessage getNewTemplateMessage() { return (DialogMessage) this.templateMessage.clone(); } public String getOriginator() { if (this.getRemoteMonitorControl() == null) { LOG.info("remoteMonitorCOntrol is null"); } if (getRemoteMonitorControl().getOriginator() == null) { LOG.info("getOriginator is null"); } return getRemoteMonitorControl().getOriginator(); } /** * Returns the system time in ms this call was started. Only valid after * call ha started */ public long getCallStartTime() { return callStartTime; } /** * Returns a formated string of the call start time */ public String getCallStartTimeString() { return new Date(callStartTime).toString(); } /** * Returns the system time is ms this call ended. Is only valid after call * has ended. */ public long getCallEndTime() { return callEndTime; } /** * Returns a formated string of hte call end time. */ public String getCallEndTimeString() { return ((callEndTime != 0) ? new Date(callEndTime).toString() : ""); } /** * Returns the time elapsed in ms from call start time. Only valid after * call has started */ public long getCallElapsedTime() { return callElapsedTime = System.currentTimeMillis() - getCallStartTime(); } /** * Returns formated string of the call elapsed time */ public String getCallElapseTimeString() { return formatElapsedTime(getCallElapsedTime()); } /** * Returns a string formated to represent hours:minutes:seconds of the time * elapsed since call start. */ protected String formatElapsedTime(long elapsedTime) { long tmp = elapsedTime; long hours = tmp / HOUR; tmp = tmp - (hours * HOUR); long minutes = tmp / MINUTE; tmp = tmp - (minutes * MINUTE); long seconds = tmp / SECOND; String timeString; timeString = String.valueOf(hours) + TIME_SEPARATOR; if (minutes < 10) { timeString = timeString + "0"; } timeString = timeString + String.valueOf(minutes) + TIME_SEPARATOR; if (seconds < 10) { timeString = timeString + "0"; } timeString = timeString + String.valueOf(seconds); return timeString; } /** * 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 final AckWaitLock ackWaitLock; private String commandName = null; private boolean threadEnded = false; private boolean threadStarted = 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 waitForStart() { if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("MessageAckThread waiting for threadstart"); } while (!this.threadStarted) { try { Thread.sleep(100); } catch (InterruptedException ix) { ix.printStackTrace(); } } if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("MessageAckThread thread started"); } } public void run() { threadStarted = true; if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("MessageAckThread : Run "); } try { synchronized (ackWaitLock) { if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("MessageAckThread : waiting!!!!!"); } ackWaitLock.wait(getMessageAckTimeout()); if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("MessageAckThread : DONE waiting!!!!!"); } } } 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"); } ViJxtaCallControl.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.notifyAll(); } } class AckWaitLock { private boolean acknowledged = false; public boolean isAcknowledged() { return acknowledged; } public void setAcknowledged(boolean acked) { this.acknowledged = acked; if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info("AckWaitLock : SetAcknowldge " + acknowledged); } } } } /** * Because we push the video 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(ViJxtaCallControl.SECOND); } catch (InterruptedException ix) { ix.printStackTrace(); } if (getProtocolState() == ViJxtaCallControl.SESSION_VIJXTA_HOLDING) { continue; } long lastMessageReceived = 0; if (remoteMonitorControl != null) { lastMessageReceived = getRemoteMonitorControl().getTimeOfLastMessage(); } long currentTime = System.currentTimeMillis(); if (getProtocolState() == ViJxtaCallControl.SESSION_VIJXTA_INCALL && (currentTime - lastMessageReceived) > getPayloadMessageTimeout()) { if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.info(" diff " + (currentTime - lastMessageReceived) + " > " + getPayloadMessageTimeout()); } ViJxtaCallControl.this.localActionMessageGoneUnAcknowledged(); } } } } class MyLock { private boolean locked = false; public boolean isLocked() { return locked; } public void setLocked(boolean locked) { this.locked = locked; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -