List of usage examples for java.nio.channels SelectionKey OP_WRITE
int OP_WRITE
To view the source code for java.nio.channels SelectionKey OP_WRITE.
Click Source Link
From source file:org.gcaldaemon.core.ldap.LDAPListener.java
private final void processRead(SelectionKey key) throws Exception { // Read packet from socket channel sleep(100);//from w w w.j a v a 2s . co m byte[] bytes = null; Object att = key.attachment(); if (att != null && att instanceof byte[]) { bytes = (byte[]) att; } SocketChannel channel = (SocketChannel) key.channel(); requestBuffer.clear(); int len = channel.read(requestBuffer); if (len == -1) { throw new IOException(); } if (len != 0) { requestBuffer.flip(); byte[] packet = new byte[len]; requestBuffer.get(packet, 0, len); if (bytes == null || bytes.length == 0) { bytes = packet; key.attach(bytes); } else { byte[] swap = new byte[bytes.length + packet.length]; System.arraycopy(bytes, 0, swap, 0, bytes.length); System.arraycopy(packet, 0, swap, bytes.length, packet.length); bytes = swap; key.attach(bytes); } // Try to process packet LdapMessageContainer container = new LdapMessageContainer(); try { ByteBuffer buffer = ByteBuffer.wrap(bytes); LdapDecoder decoder = new LdapDecoder(); decoder.decode(buffer, container); } catch (DecoderException emptyStringException) { String msg = emptyStringException.getMessage(); if (msg != null && (msg.indexOf("empty") != -1 || msg.indexOf("transition") != -1)) { // All contacts requested int id = container.getMessageId(); SearchRequest search = new SearchRequest(); search.setMessageId(id); LdapMessage ldap = new LdapMessage(); ldap.setMessageId(id); ldap.setProtocolOP(search); container.setLdapMessage(ldap); } else { throw emptyStringException; } } // Process LDAP request ByteBuffer response = processRequest(container.getLdapMessage(), !container.isGrammarEndAllowed()); key.attach(response); key.interestOps(SelectionKey.OP_WRITE); } }
From source file:org.gldapdaemon.core.ldap.LDAPListener.java
private final void processRead(SelectionKey key) throws Exception { // Read packet from socket channel sleep(100);//from w ww . ja v a2 s. co m byte[] bytes = null; Object att = key.attachment(); if (att != null && att instanceof byte[]) { bytes = (byte[]) att; } SocketChannel channel = (SocketChannel) key.channel(); requestBuffer.clear(); int len = channel.read(requestBuffer); if (len == -1) { throw new IOException(); } if (len != 0) { requestBuffer.flip(); byte[] packet = new byte[len]; requestBuffer.get(packet, 0, len); if (bytes == null || bytes.length == 0) { bytes = packet; key.attach(bytes); } else { byte[] swap = new byte[bytes.length + packet.length]; System.arraycopy(bytes, 0, swap, 0, bytes.length); System.arraycopy(packet, 0, swap, bytes.length, packet.length); bytes = swap; key.attach(bytes); } // Try to process packet LdapMessageContainer container = new LdapMessageContainer(); try { ByteBuffer buffer = ByteBuffer.wrap(bytes); LdapDecoder decoder = new LdapDecoder(); decoder.decode(buffer, container); } catch (DecoderException emptyStringException) { String msg = emptyStringException.getMessage(); if (msg != null && (msg.indexOf("empty") != -1 || msg.indexOf("transition") != -1)) { // All contacts requested int id = container.getMessageId(); SearchRequest search = new SearchRequest(); search.setMessageId(id); LdapMessage ldap = new LdapMessage(); ldap.setMessageId(id); ldap.setProtocolOP(search); container.setLdapMessage(ldap); } else { throw emptyStringException; } } // Process LDAP request ByteBuffer response = processRequest(container.getLdapMessage(), !container.isGrammarEndAllowed()); key.attach(response); key.interestOps(SelectionKey.OP_WRITE); } }
From source file:org.limewire.mojito.io.MessageDispatcherImpl.java
/** * Called to indicate an interest in writing something to * the Network. Override this method if you need this functionality! *//* www.j a v a 2 s . c om*/ private void interestWrite(boolean on) { interest(SelectionKey.OP_WRITE, on); }
From source file:org.openhab.binding.irtrans.handler.EthernetBridgeHandler.java
private void establishConnection() { lock.lock();/*from w w w. j a va 2 s .c o m*/ try { if (getConfig().get(IP_ADDRESS) != null && getConfig().get(PORT_NUMBER) != null) { try { socketChannel = SocketChannel.open(); socketChannel.socket().setKeepAlive(true); socketChannel.configureBlocking(false); synchronized (selector) { selector.wakeup(); int interestSet = SelectionKey.OP_READ | SelectionKey.OP_WRITE | SelectionKey.OP_CONNECT; socketChannelKey = socketChannel.register(selector, interestSet); } InetSocketAddress remoteAddress = new InetSocketAddress((String) getConfig().get(IP_ADDRESS), ((BigDecimal) getConfig().get(PORT_NUMBER)).intValue()); socketChannel.connect(remoteAddress); } catch (IOException e) { logger.debug("An exception occurred while connecting to '{}:{}' : {}", getConfig().get(IP_ADDRESS), ((BigDecimal) getConfig().get(PORT_NUMBER)).intValue(), e.getMessage()); updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage()); } try { Thread.sleep(((BigDecimal) getConfig().get(RESPONSE_TIME_OUT)).intValue()); } catch (NumberFormatException | InterruptedException e) { Thread.currentThread().interrupt(); logger.debug("An exception occurred while putting a thread to sleep: '{}'", e.getMessage()); updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage()); } onConnectable(); } } finally { lock.unlock(); } }
From source file:org.openhab.binding.keba.handler.KeContactHandler.java
private void establishConnection() { lock.lock();/*from w ww.j a v a 2 s .c om*/ try { if (getThing().getStatusInfo().getStatusDetail() != ThingStatusDetail.CONFIGURATION_ERROR && getConfig().get(IP_ADDRESS) != null && !getConfig().get(IP_ADDRESS).equals("")) { try { datagramChannel = DatagramChannel.open(); } catch (Exception e2) { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "An exception occurred while opening a datagram channel"); } try { datagramChannel.configureBlocking(false); } catch (IOException e2) { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "An exception occurred while configuring a datagram channel"); } synchronized (selector) { selector.wakeup(); int interestSet = SelectionKey.OP_READ | SelectionKey.OP_WRITE; try { datagramChannelKey = datagramChannel.register(selector, interestSet); } catch (ClosedChannelException e1) { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "An exception occurred while registering a selector"); } InetSocketAddress remoteAddress = new InetSocketAddress((String) getConfig().get(IP_ADDRESS), REMOTE_PORT_NUMBER); try { logger.trace("Connecting the channel for {} ", remoteAddress); datagramChannel.connect(remoteAddress); onConnectionResumed(); } catch (Exception e) { logger.error("An exception occurred while connecting connecting to '{}:{}' : {}", new Object[] { (String) getConfig().get(IP_ADDRESS), REMOTE_PORT_NUMBER, e.getMessage() }); updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "An exception occurred while connecting"); } } } else { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, getThing().getStatusInfo().getDescription()); } } finally { lock.unlock(); } }
From source file:org.openhab.binding.mart.handler.martHandler.java
/** * establishes a connection for reading and writing *//*w w w . j av a 2 s .c om*/ private void establishConnection() { lock.lock(); try { // returns the thing which belongs to the handler // gets the status information of the thing // gets the detail of the status and checks if there are no configuration errors // and checks if the ipAddress is not null or empty if (getThing().getStatusInfo().getStatusDetail() != ThingStatusDetail.CONFIGURATION_ERROR && getConfig().get(IP_ADDRESS) != null || getConfig().get(IP_ADDRESS) != "") { try { // opens a datagram channel datagramChannel = DatagramChannel.open(); } catch (Exception e) { // updates the status of the thing updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "An exception occurred while creating a datagram channel"); } try { // The Channel must be in non-blocking mode to be used with a Selector datagramChannel.configureBlocking(false); } catch (IOException e) { // updates the status of the thing updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "An error occurred while creating a datagram channel"); } synchronized (selector) { selector.wakeup(); // The interest set is the set of events you are interested in "selecting" int interestSet = SelectionKey.OP_READ | SelectionKey.OP_WRITE; try { // registers this channel with the given selector, returning a selectionKey datagramChannelKey = datagramChannel.register(selector, interestSet); } catch (ClosedChannelException e) { // updates the status of the thing updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "An exception occured while registering a channel"); } // creating an IP Socket Address (remoteAddress) for the remote port number InetSocketAddress remoteAddress = new InetSocketAddress((String) getConfig().get(IP_ADDRESS), REMOTE_PORT_NUMBER); try { logger.trace("Connecting to the channel for {}", remoteAddress); // connects this channel's socket to the given remote peer address datagramChannel.connect(remoteAddress); // after connection update the status of the thing to Online onConnectionResumed(); } catch (Exception e) { logger.error("An error occured while connecting connecting to '{}:{}' : {}", new Object[] { (String) getConfig().get(IP_ADDRESS) }, REMOTE_PORT_NUMBER, e.getMessage()); // update the status of the thing updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, " An excepton ocurred while connecting"); } } } else { // update the status of the thing updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, getThing().getStatusInfo().getDescription()); } } finally { lock.unlock(); } }
From source file:org.openhab.binding.tcp.AbstractSocketChannelBinding.java
/** * @{inheritDoc}/*from w ww .j a v a 2 s . c om*/ */ @Override protected void execute() { // Cycle through the Items and setup channels if required for (P provider : providers) { for (String itemName : provider.getItemNames()) { for (Command aCommand : ((P) provider).getAllCommands(itemName)) { String remoteHost = ((P) provider).getHost(itemName, aCommand); String remotePort = ((P) provider).getPortAsString(itemName, aCommand); Direction direction = ((P) provider).getDirection(itemName, aCommand); InetSocketAddress remoteAddress = null; if (!(remoteHost.equals("*") || remotePort.equals("*"))) { remoteAddress = new InetSocketAddress(remoteHost, Integer.parseInt(remotePort)); } Channel newChannel = null; Channel existingChannel = null; if (useAddressMask && (remoteHost.equals("*") || remotePort.equals("*"))) { newChannel = new Channel(itemName, aCommand, remoteHost, remotePort, ((P) provider).getDirection(itemName, aCommand), false, null, false, null); existingChannel = channels.get(itemName, aCommand, direction, remoteHost, remotePort); } else { newChannel = new Channel(itemName, aCommand, remoteAddress, ((P) provider).getDirection(itemName, aCommand), false, null, false, null); existingChannel = channels.get(itemName, aCommand, direction, remoteAddress); } if (existingChannel == null) { if (direction == Direction.IN) { boolean assigned = false; if (useAddressMask && (remoteHost.equals("*") || remotePort.equals("*"))) { logger.warn( "When using address masks we will not verify if we are already listening to similar incoming connections"); logger.info("We will accept data coming from the remote end {}:{}", remoteHost, remotePort); channels.add(newChannel); } else { if (itemShareChannels) { Channel firstChannel = channels.getFirstServed(itemName, direction, remoteAddress); if (firstChannel != null) { newChannel.channel = firstChannel.channel; assigned = true; } } if (bindingShareChannels) { Channel firstChannel = channels.getFirstServed(direction, remoteAddress); if (firstChannel != null) { newChannel.channel = firstChannel.channel; assigned = true; } } if (directionsShareChannels) { Channel firstChannel = channels.getFirstServed(remoteAddress); if (firstChannel != null) { newChannel.channel = firstChannel.channel; assigned = true; } } if (!assigned || newChannel.channel == null) { if (channels.contains(itemName, aCommand, Direction.IN, remoteAddress)) { logger.warn("We already listen for incoming connections from {}", remoteAddress); } else { logger.debug("Setting up the inbound channel {}", newChannel); channels.add(newChannel); logger.info("We will accept data coming from the remote end {}", remoteAddress); } } } } else if (direction == Direction.OUT) { boolean assigned = false; if (useAddressMask && (remoteHost.equals("*") || remotePort.equals("*"))) { logger.error( "We do not accept outgoing connections for Items that do use address masks"); } else { channels.add(newChannel); if (newChannel.channel == null) { if (itemShareChannels) { Channel firstChannel = channels.getFirstServed(itemName, direction, remoteAddress); if (firstChannel != null) { newChannel.channel = firstChannel.channel; assigned = true; } } if (bindingShareChannels) { Channel firstChannel = channels.getFirstServed(direction, remoteAddress); if (firstChannel != null) { newChannel.channel = firstChannel.channel; assigned = true; } } if (directionsShareChannels) { Channel firstChannel = channels.getFirstServed(remoteAddress); if (firstChannel != null) { newChannel.channel = firstChannel.channel; assigned = true; } } if (assigned) { logger.debug("Setting up the outbound assigned channel {} ", newChannel); } synchronized (this) { if (!assigned || newChannel.channel == null) { SocketChannel newSocketChannel = null; try { newSocketChannel = SocketChannel.open(); } catch (IOException e2) { logger.error("An exception occurred while opening a channel: {}", e2.getMessage()); } try { newSocketChannel.socket().setKeepAlive(true); newSocketChannel.configureBlocking(false); } catch (IOException e) { logger.error( "An exception occurred while configuring a channel: {}", e.getMessage()); } synchronized (selector) { selector.wakeup(); int interestSet = SelectionKey.OP_READ | SelectionKey.OP_WRITE | SelectionKey.OP_CONNECT; try { newSocketChannel.register(selector, interestSet); } catch (ClosedChannelException e1) { logger.error( "An exception occurred while registering a selector: {}", e1.getMessage()); } } newChannel.channel = newSocketChannel; logger.debug("Setting up the outbound channel {}", newChannel); try { logger.info("Connecting the channel {} ", newChannel); newSocketChannel.connect(remoteAddress); } catch (IOException e) { logger.error("An exception occurred while connecting a channel: {}", e.getMessage()); } } } } else { logger.info("There is already an active channel {} for the remote end {}", newChannel.channel, newChannel.remote); } } } } } } } // Check on channels for which we have to process data synchronized (selector) { try { // Wait for an event selector.selectNow(); } catch (IOException e) { logger.error("An exception occurred while Selecting ({})", e.getMessage()); } } // Get list of selection keys with pending events Iterator<SelectionKey> it = selector.selectedKeys().iterator(); // Process each key at a time while (it.hasNext()) { SelectionKey selKey = (SelectionKey) it.next(); it.remove(); if (selKey.isValid()) { if (selKey == listenerKey) { if (selKey.isAcceptable()) { try { SocketChannel newChannel = listenerChannel.accept(); logger.info("Received connection request from {}", newChannel.getRemoteAddress()); Channel firstChannel = channels.getFirstNotServed(Direction.IN, (InetSocketAddress) newChannel.getRemoteAddress()); if (firstChannel != null) { if (firstChannel.direction == Direction.IN) { if (useAddressMask && (firstChannel.host.equals("*") || firstChannel.port.equals("*"))) { logger.info( "{}:{} is an allowed masked remote end. The channel will now be configured", firstChannel.host, firstChannel.port); } else { logger.info( "{} is an allowed remote end. The channel will now be configured", firstChannel.remote); } if (firstChannel.channel == null || !firstChannel.channel.isOpen()) { firstChannel.channel = newChannel; firstChannel.isBlocking = false; firstChannel.buffer = null; if (itemShareChannels) { channels.replace(firstChannel.item, firstChannel.direction, (InetSocketAddress) newChannel.getRemoteAddress(), firstChannel.channel); } if (bindingShareChannels) { channels.replace(firstChannel.direction, (InetSocketAddress) newChannel.getRemoteAddress(), firstChannel.channel); } if (directionsShareChannels) { channels.replace((InetSocketAddress) newChannel.getRemoteAddress(), firstChannel.channel); } try { newChannel.configureBlocking(false); //setKeepAlive(true); } catch (IOException e) { logger.error("An exception occurred while configuring a channel: {}", e.getMessage()); } synchronized (selector) { selector.wakeup(); try { newChannel.register(selector, newChannel.validOps()); } catch (ClosedChannelException e1) { logger.error( "An exception occurred while registering a selector: {}", e1.getMessage()); } } Scheduler scheduler = null; try { scheduler = StdSchedulerFactory.getDefaultScheduler(); } catch (SchedulerException e1) { logger.error( "An exception occurred while getting the Quartz scheduler: {}", e1.getMessage()); } JobDataMap map = new JobDataMap(); map.put("Channel", firstChannel); map.put("Binding", this); JobDetail job = newJob(ConfigureJob.class).withIdentity( Integer.toHexString(hashCode()) + "-Configure-" + Long.toString(System.currentTimeMillis()), this.toString()).usingJobData(map).build(); Trigger trigger = newTrigger().withIdentity( Integer.toHexString(hashCode()) + "-Configure-" + Long.toString(System.currentTimeMillis()), this.toString()).startNow().build(); try { if (job != null && trigger != null && selKey != listenerKey) { scheduler.scheduleJob(job, trigger); } } catch (SchedulerException e) { logger.error( "An exception occurred while scheduling a job with the Quartz Scheduler {}", e.getMessage()); } } else { logger.info( "We previously already accepted a connection from the remote end {} for this channel. Goodbye", firstChannel.remote); newChannel.close(); } } else { logger.info( "Disconnecting the remote end {} that tries to connect an outbound only port", newChannel.getRemoteAddress()); newChannel.close(); } } else { logger.info("Disconnecting the unallowed remote end {}", newChannel.getRemoteAddress()); newChannel.close(); } } catch (IOException e) { logger.error("An exception occurred while configuring a channel: {}", e.getMessage()); } } } else { SocketChannel theSocketChannel = (SocketChannel) selKey.channel(); Channel theChannel = channels.get(theSocketChannel); if (selKey.isConnectable()) { channels.setAllReconnecting(theSocketChannel, false); boolean result = false; boolean error = false; try { result = theSocketChannel.finishConnect(); } catch (NoConnectionPendingException e) { // this channel is not connected and a connection operation // has not been initiated logger.warn("The channel {} has no connection pending ({})", theSocketChannel, e.getMessage()); error = true; } catch (ClosedChannelException e) { // If some other I/O error occurs logger.warn("The channel {} is closed ({})", theSocketChannel, e.getMessage()); error = true; } catch (IOException e) { // If some other I/O error occurs logger.warn("The channel {} has encountered an unknown IO Exception: {}", theSocketChannel, e.getMessage()); error = true; } if (error) { Scheduler scheduler = null; try { scheduler = StdSchedulerFactory.getDefaultScheduler(); } catch (SchedulerException e1) { logger.error("An exception occurred while getting the Quartz scheduler: {}", e1.getMessage()); } JobDataMap map = new JobDataMap(); map.put("Channel", theChannel); map.put("Binding", this); JobDetail job = newJob(ReconnectJob.class) .withIdentity(Integer.toHexString(hashCode()) + "-Reconnect-" + Long.toString(System.currentTimeMillis()), this.toString()) .usingJobData(map).build(); Trigger trigger = newTrigger() .withIdentity(Integer.toHexString(hashCode()) + "-Reconnect-" + Long.toString(System.currentTimeMillis()), this.toString()) .startAt(futureDate(reconnectInterval, IntervalUnit.SECOND)).build(); try { if (job != null && trigger != null && selKey != listenerKey) { if (!theChannel.isReconnecting) { channels.setAllReconnecting(theSocketChannel, true); scheduler.scheduleJob(job, trigger); } } } catch (SchedulerException e) { logger.error( "An exception occurred while scheduling a job with the Quartz Scheduler {}", e.getMessage()); } } else { if (result) { InetSocketAddress remote = null; try { remote = (InetSocketAddress) theSocketChannel.getRemoteAddress(); } catch (IOException e) { logger.error( "An exception occurred while getting the remote address of channel {} ({})", theSocketChannel, e.getMessage()); } logger.info("The channel for {} is now connected", remote); if (itemShareChannels) { channels.replace(theChannel.item, theChannel.direction, remote, theChannel.channel); } if (bindingShareChannels) { channels.replace(theChannel.direction, remote, theChannel.channel); } if (directionsShareChannels) { channels.replace(remote, theChannel.channel); } Scheduler scheduler = null; try { scheduler = StdSchedulerFactory.getDefaultScheduler(); } catch (SchedulerException e1) { logger.error("An exception occurred while getting the Quartz scheduler: {}", e1.getMessage()); } JobDataMap map = new JobDataMap(); map.put("Channel", theChannel); map.put("Binding", this); JobDetail job = newJob(ConfigureJob.class) .withIdentity( Integer.toHexString(hashCode()) + "-Configure-" + Long.toString(System.currentTimeMillis()), this.toString()) .usingJobData(map).build(); Trigger trigger = newTrigger() .withIdentity( Integer.toHexString(hashCode()) + "-Configure-" + Long.toString(System.currentTimeMillis()), this.toString()) .startNow().build(); try { if (job != null && trigger != null && selKey != listenerKey) { scheduler.scheduleJob(job, trigger); } } catch (SchedulerException e) { logger.error( "An exception occurred while scheduling a job with the Quartz Scheduler {}", e.getMessage()); } job = newJob(ReconnectJob.class) .withIdentity( Integer.toHexString(hashCode()) + "-Reconnect-" + Long.toString(System.currentTimeMillis()), this.toString()) .usingJobData(map).build(); trigger = newTrigger() .withIdentity( Integer.toHexString(hashCode()) + "-Reconnect-" + Long.toString(System.currentTimeMillis()), this.toString()) .withSchedule(cronSchedule(reconnectCron)).build(); try { if (job != null && trigger != null && selKey != listenerKey) { scheduler.scheduleJob(job, trigger); } } catch (SchedulerException e) { logger.error( "An exception occurred while scheduling a job with the Quartz Scheduler {}", e.getMessage()); } } } } else if (selKey.isReadable()) { ByteBuffer readBuffer = ByteBuffer.allocate(maximumBufferSize); int numberBytesRead = 0; boolean error = false; try { //TODO: Additional code to split readBuffer in multiple parts, in case the data send by the remote end is not correctly fragemented. Could be handed of to implementation class if for example, the buffer needs to be split based on a special character like line feed or carriage return numberBytesRead = theSocketChannel.read(readBuffer); } catch (NotYetConnectedException e) { logger.warn("The channel for {} has no connection pending ({})", theChannel.remote, e.getMessage()); if (!theSocketChannel.isConnectionPending()) { error = true; } } catch (IOException e) { // If some other I/O error occurs logger.warn("The channel for {} has encountered an unknown IO Exception: {}", theChannel.remote, e.getMessage()); error = true; } if (numberBytesRead == -1) { try { theSocketChannel.close(); } catch (IOException e) { logger.warn("The channel for {} is closed ({})", theChannel.remote, e.getMessage()); } error = true; } if (error) { if (theChannel.direction == Direction.OUT) { Scheduler scheduler = null; try { scheduler = StdSchedulerFactory.getDefaultScheduler(); } catch (SchedulerException e1) { logger.error("An exception occurred while getting the Quartz scheduler: {}", e1.getMessage()); } JobDataMap map = new JobDataMap(); map.put("Channel", theChannel); map.put("Binding", this); JobDetail job = newJob(ReconnectJob.class).withIdentity( Integer.toHexString(hashCode()) + "-Reconnect-" + Long.toString(System.currentTimeMillis()), "AbstractSocketChannelBinding").usingJobData(map).build(); Trigger trigger = newTrigger() .withIdentity( Integer.toHexString(hashCode()) + "-Reconnect-" + Long.toString(System.currentTimeMillis()), "AbstractSocketChannelBinding") .startAt(futureDate(reconnectInterval, IntervalUnit.SECOND)).build(); try { if (job != null && trigger != null && selKey != listenerKey) { if (!theChannel.isReconnecting) { channels.setAllReconnecting(theSocketChannel, true); scheduler.scheduleJob(job, trigger); } } } catch (SchedulerException e) { logger.error( "An exception occurred while scheduling a job with the Quartz Scheduler {}", e.getMessage()); } } else { theChannel.channel = null; } } else { ArrayList<Channel> channelsToServe = new ArrayList<Channel>(); channelsToServe = channels.getAll(theSocketChannel); if (channelsToServe.size() > 0) { readBuffer.flip(); boolean isBlocking = channels.isBlocking(theSocketChannel); if (isBlocking) { // if we are in a blocking operation, we get are now finished and we have to reset the flag. The read buffer will be returned to the instance // that initiated the write opreation - it has to parse the buffer itself theChannel = channels.getBlocking(theSocketChannel); theChannel.buffer = readBuffer; theChannel.isBlocking = false; } else { for (Channel aChannel : channelsToServe) { // if not, then we parse the buffer as ususal parseChanneledBuffer(aChannel, readBuffer); } } } else { try { logger.warn( "No channel is active or defined for the data we received from {}. It will be discarded.", theSocketChannel.getRemoteAddress()); } catch (IOException e) { logger.error( "An exception occurred while getting the remote address of the channel {} ({})", theSocketChannel, e.getMessage()); } } } } else if (selKey.isWritable()) { boolean isBlocking = channels.isBlocking(theSocketChannel); if (isBlocking) { // if this channel is already flagged as being in a blocked write/read operation, we skip this selKey } else { // pick up a QueueElement for this channel, if any WriteBufferElement theElement = null; Iterator<WriteBufferElement> iterator = writeQueue.iterator(); while (iterator.hasNext()) { WriteBufferElement anElement = iterator.next(); if (anElement.channel.channel.equals(theSocketChannel)) { theElement = anElement; break; } } if (theElement != null && theElement.buffer != null) { logger.debug("Picked {} from the queue", theElement); if (theElement.isBlocking) { theElement.channel.isBlocking = true; } boolean error = false; theElement.buffer.rewind(); try { logger.debug("Sending {} for the outbound channel {}->{}", new Object[] { new String(theElement.buffer.array()), theElement.channel.channel.getLocalAddress(), theElement.channel.channel.getRemoteAddress() }); theSocketChannel.write(theElement.buffer); } catch (NotYetConnectedException e) { logger.warn("The channel for {} has no connection pending ({})", theChannel.remote, e.getMessage()); if (!theSocketChannel.isConnectionPending()) { error = true; } } catch (ClosedChannelException e) { // If some other I/O error occurs logger.warn("The channel for {} is closed ({})", theChannel.remote, e.getMessage()); error = true; } catch (IOException e) { // If some other I/O error occurs logger.warn("The channel for {} has encountered an unknown IO Exception: {}", theChannel.remote, e.getMessage()); error = true; } if (error) { if (theElement.channel.direction == Direction.OUT) { Scheduler scheduler = null; try { scheduler = StdSchedulerFactory.getDefaultScheduler(); } catch (SchedulerException e1) { logger.error( "An exception occurred while getting the Quartz scheduler: {}", e1.getMessage()); } JobDataMap map = new JobDataMap(); map.put("Channel", theElement.channel); map.put("Binding", this); JobDetail job = newJob(ReconnectJob.class).withIdentity( Integer.toHexString(hashCode()) + "-Reconnect-" + Long.toString(System.currentTimeMillis()), "AbstractSocketChannelBinding").usingJobData(map).build(); Trigger trigger = newTrigger() .withIdentity( Integer.toHexString(hashCode()) + "-Reconnect-" + Long.toString(System.currentTimeMillis()), "AbstractSocketChannelBinding") .startAt(futureDate(reconnectInterval, IntervalUnit.SECOND)) .build(); try { if (job != null && trigger != null && selKey != listenerKey) { if (!theElement.channel.isReconnecting) { channels.setAllReconnecting(theSocketChannel, true); scheduler.scheduleJob(job, trigger); } } } catch (SchedulerException e) { logger.error( "An exception occurred while scheduling a job with the Quartz Scheduler {}", e.getMessage()); } } else { theElement.channel.channel = null; } } else { if (theElement != null) { writeQueue.remove(theElement); } } } } } } } } }
From source file:org.openhab.io.transport.cul.internal.network.CULNetworkHandlerImpl.java
private void send(ByteBuffer buffer) throws InterruptedException, IOException { if (!connected.get()) { throw new IOException("not connected"); }//from w ww. j a va2s.com synchronized (writeBuf) { // try direct write of what's in the buffer to free up space if (writeBuf.remaining() < buffer.remaining()) { writeBuf.flip(); int bytesOp = 0, bytesTotal = 0; while (writeBuf.hasRemaining() && (bytesOp = channel.write(writeBuf)) > 0) { bytesTotal += bytesOp; } writeBuf.compact(); logger.debug("Written {} bytes to the network", bytesTotal); } // if didn't help, wait till some space appears if (Thread.currentThread().getId() != thread.getId()) { while (writeBuf.remaining() < buffer.remaining()) { writeBuf.wait(); } } else { if (writeBuf.remaining() < buffer.remaining()) { throw new IOException("send buffer full"); // TODO: add reallocation or buffers chain } } writeBuf.put(buffer); // try direct write to decrease the latency writeBuf.flip(); int bytesOp = 0, bytesTotal = 0; while (writeBuf.hasRemaining() && (bytesOp = channel.write(writeBuf)) > 0) { bytesTotal += bytesOp; } writeBuf.compact(); logger.debug("Written {} bytes to the network", bytesTotal); if (writeBuf.hasRemaining()) { SelectionKey key = channel.keyFor(selector); key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); selector.wakeup(); } } }
From source file:org.openhab.io.transport.cul.internal.network.CULNetworkHandlerImpl.java
private void processWrite(SelectionKey key) throws IOException { WritableByteChannel ch = (WritableByteChannel) key.channel(); synchronized (writeBuf) { writeBuf.flip();/* www . j a v a 2 s.co m*/ int bytesOp = 0, bytesTotal = 0; while (writeBuf.hasRemaining() && (bytesOp = ch.write(writeBuf)) > 0) { bytesTotal += bytesOp; } logger.debug("Written {} bytes to the network", bytesTotal); if (writeBuf.remaining() == 0) { key.interestOps(key.interestOps() ^ SelectionKey.OP_WRITE); } if (bytesTotal > 0) { writeBuf.notify(); } else if (bytesOp == -1) { logger.info("peer closed write channel"); ch.close(); } writeBuf.compact(); } }
From source file:org.pvalsecc.comm.ServerConnection.java
/** * Asynchronous. Just queue the data to be sent and tell the selector we want to send some data. When ready, * {@code send} will be called./*from ww w. j av a2s. c om*/ */ protected synchronized void answer(ByteBuffer buffer) { toSend.add(buffer); key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE); key.selector().wakeup(); }