短信"猫"可以实现无手机发送短信,和mas机比起来就是比较灵活点,不用那么多繁杂的步骤。
一般来说,对于信息的处理无外乎两种方式:一种是把任务保存到缓存队列中,然后去调度任务.优点就是速度快,缺点也很明显,如果任务处理的不好,很容出现任务无法执行或者等待.另一种就是保存到数据库中,短信发送和数据的处理分开处理,但是速度方面会有影响.这里说的第二种方法。
首先把任务的数据保存到数据库中,这块的话没有什么难度,就是普通的增删改查.
发送短信的单独分离出来运行,即web端和发送端分开.
首先需要初始化设备
- public static void initDriver() {
- if (!initDriver) {
- initDriver = true;
- String driverName = "com.sun.comm.Win32Driver";
- String libname = "win32com";
- CommDriver commDriver = null;
- try {
- System.loadLibrary("win32com");
- log.info(libname + " Library Loaded");
-
- commDriver = (CommDriver) Class.forName(driverName)
- .newInstance();
- commDriver.initialize();
- log.info("comm Driver Initialized");
-
- } catch (Exception e) {
- log.error(e.getMessage(), e);
- }
- }
- }
然后需要查找SMS设备
- public static List<String> findSMS() {
- TreeMap<String, String> portsMap = new TreeMap<String, String>();
- log.info("GSM Modem 串行端口连接测试开始...");
- Enumeration<?> en = CommPortIdentifier.getPortIdentifiers();
- CommPortIdentifier portId;
- while (en.hasMoreElements()) {
- portId = (CommPortIdentifier) en.nextElement();
- if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
- if (checkCommPortForSMS(portId.getName())) {
- log.info(" 设备端口 : " + portId.getName() + " 满足短信<strong>发送</strong>要求");
- portsMap.put(portId.getName(), portId.getName());
- }
- }
- }
- log.info("GSM Modem 检查结束 ...");
- return new Vector<String>(portsMap.keySet());
- }
- public static boolean checkCommPortForSMS(String portName) {
- portList = CommPortIdentifier.getPortIdentifiers();
- while (portList.hasMoreElements()) {
- portId = (CommPortIdentifier) portList.nextElement();
- if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL
- && portName.equals(portId.getName())) {
- log.info("找到串口: " + portId.getName());
- for (int i = 0; i < bauds.length; i++) {
- log.info(" Trying at " + bauds[i] + "...");
- try {
- SerialPort serialPort;
- InputStream inStream;
- OutputStream outStream;
- int c;
- StringBuffer response = new StringBuffer();
- serialPort = (SerialPort) portId.open(
- "SMSLibCommTester", 2000);
- serialPort
- .setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN);
- serialPort.setSerialPortParams(bauds[i],
- SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
- SerialPort.PARITY_NONE);
- inStream = serialPort.getInputStream();
- outStream = serialPort.getOutputStream();
- serialPort.enableReceiveTimeout(1000);
- c = inStream.read();
- while (c != -1) {
- c = inStream.read();
- }
- outStream.write('A');
- outStream.write('T');
- outStream.write('\r');
- try {
- Thread.sleep(1000);
- } catch (Exception e) {
- log.error(e.getMessage(), e);
- }
- c = inStream.read();
- while (c != -1) {
- response.append((char) c);
- c = inStream.read();
- }
- if (response.indexOf("OK") >= 0) {
- log.info(" 正在检测设备:");
- try {
- outStream.write('A');
- outStream.write('T');
- outStream.write('+');
- outStream.write('C');
- outStream.write('G');
- outStream.write('M');
- outStream.write('M');
- outStream.write('\r');
- response = new StringBuffer();
- c = inStream.read();
- while (c != -1) {
- response.append((char) c);
- c = inStream.read();
- }
-
- log.info(" 发现设备: "
- + response.toString().replaceAll(
- "(\\s+OK\\s+)|[\n\r]", ""));
- if (!"ERROR".equals(response.toString()
- .replaceAll("(\\s+OK\\s+)|[\n\r]", "")
- .trim())) {
- serialPort.close();
- inStream.close();
- outStream.close();
- return true;
- }
- return false;
- } catch (Exception e) {
- log.info(" 检测设备失败,获取设备信息异常:" + e.getMessage());
- }
- } else {
- log.info(" 检测设备失败,没有接收到响应结果!");
- }
- serialPort.close();
- } catch (Exception e) {
- log.info(" 检测设备失败,发生异常:" + e.getMessage());
- }
- }
- }
- }
- return false;
- }
调用结束后会返回当前计算机可用的端口号,然后就可以注册gateway了
- for (String portId : ports) {
- SerialModemGateway gateway = new SerialModemGateway(
- "modem.MAGUS" + portId, portId, 9600, "wavecom", "");
- gateway.setInbound(true);
- gateway.setOutbound(true);
- smsService.addGateway(gateway);
- }
然后需要设置smsService的各种监听事件了.这些都搞定之后就可以设置一个while(true)循环去不停的读取数据库发送短信了,但是有一点,需要设置一个安全的线程去执行,同时还要添加同步锁.保证当前只有一个工作在进行.
--转自