Netty Pure Java Serial Port

转自:文章原地址

Intro

Typically when interacting with serial ports from Java you have three options:

All are actually mature solutions but SerialIO is a commercial product and JSS and RxTx either require the native libraries to be intalled/compiled for the host platform. Personally, I’ve had issues with RxTx and the C++ source code can be a bit difficult to understand when a problem arrises.

Solution

PureJavaComm is a solution which I’ve had the privilege to work with extensively. What’s nice about PureJavaComm is that it is entirely written in Java except for specific calls to platform functions which leverage JNA. In their own words:

PJC is written 100% in Java so it is easy for Java programmers to develop and debug and it requires no native libraries. Native access to the underlaying operating system’s serial port programming interface is provided by the wonderful JNA library which takes away all the pain of compiling and deploying native code.

In my own use, I’ve found PureJavaComm to be extremely easy to use and extend to serial devices with their own platform libraries by leveraging JNAerator to generate JNA wrappers to library code.

Netty And Serial

Netty already provides an excellent wrapper to interacting with a serial port at the application level via the RxTx transport. However, as mentioned above you still need the native libraries installed. To alleviate this, I’ve created Netty Transport PureJavaComm
Here’s a quick sample based on the existing Netty RxTx code:

package com.beauhinks.example.purejavacomm;

import com.beauhinks.purejavacomm.PureJavaCommChannel;
import com.beauhinks.purejavacomm.PureJavaCommDeviceAddress;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.oio.OioEventLoopGroup;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import purejavacomm.CommPortIdentifier;

import java.util.Enumeration;


/**
 * Sends one message to a serial device
 */
public final class PureJavaCommClient {
    public static void main(String[] args) throws Exception {
        CommPortIdentifier portid = null;
        Enumeration e = CommPortIdentifier.getPortIdentifiers();
        while (e.hasMoreElements()) {
            portid = (CommPortIdentifier) e.nextElement();
            System.out.println("found " + portid.getName());
        }
        EventLoopGroup group = new OioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(PureJavaCommChannel.class)
                    .handler(new ChannelInitializer<PureJavaCommChannel>() {
                        @Override
                        public void initChannel(PureJavaCommChannel ch) throws Exception {
                            ch.pipeline().addLast(
                                    new LineBasedFrameDecoder(32768),
                                    new StringEncoder(),
                                    new StringDecoder(),
                                    new PureJavaCommClientHandler()
                            );
                        }
                    });

            ChannelFuture f = b.connect(new PureJavaCommDeviceAddress("/dev/ttyS0")).sync();
            f.channel().write()
            f.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }
    }

    private PureJavaCommClient() {
    }
}

To get up and running and test the code there are two VM’s in the develop branch, master and slave. Start the master with vagrant up and then cd into the slave directory and start the slave with vagrant up. cd to /Vagrant and run mvn exec:java to run the samples. The master and slave VM’s will then exchange messages over a simulated serialport via a host named pipe. The great thing about using Netty to interact with a serial port is that you can easily integrate Kryo, MsgPack, or JSON into your pipeline to handle serialization and pass arbitrary POJOS or commands over a serial port without writing a bunch of one-off parsing logic typically seen when dealing with serial ports.

Fork and enjoy.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值