主动触发式接口的设计与实现

本文介绍了一个基于IDCC的家庭网关触发器设计,包括使用Oracle PL/SQL创建触发器、告信者过程以及单线程服务端实现。触发器监测状态变化并启动任务发送消息给服务端。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、触发器的设计,采用队列机制避免阻塞
create or replace trigger new97es_idcc_trigger_fg
  after insert or update of STATE on SPJK_FAMILY_GATEWAY
  for each row
declare
  -- local variables here
  job BINARY_INTEGER;

begin
  if 'D' = :new.state then
    DBMS_JOB.SUBMIT(job,
                    'new97es_spjk_messenger(''127.0.0.1'',''7008'',''IDCC[' ||
                    :new.SPJK_TYPE_ID || ']'');',
                    sysdate,
                    null,
                    false);
  end if;
exception
  when others then
    null;
end new97es_idcc_trigger_fg;
2、告信者的实现
create or replace procedure new97es_spjk_messenger(remote_host  varchar2,
                                                   remote_port  binary_integer,
                                                   send_message varchar2) is
  c utl_tcp.connection;
  i pls_integer;
begin
  -- check parameters
  if (remote_host is null) or (remote_port is null) or
     (send_message is null) then
    return;
  end if;

  begin
    -- open connection  
    c := utl_tcp.open_connection(remote_host,
                                 remote_port,
                                 null,
                                 null,
                                 null,
                                 null,
                                 'UTF-8',
                                 null,
                                 0);
    -- send message
    i := utl_tcp.write_line(c, send_message);
    -- close connection
    utl_tcp.close_connection(c);
  exception
    when others then
      null;
  end;

end new97es_spjk_messenger;
3、单线程服务端的实现,通过plugin启动
package new97es.web.service;

import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.net.*;
import java.util.*;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class InterfaceDataControlCenterServer extends Thread {
 private static Log log = LogFactory
   .getLog(InterfaceDataControlCenterServer.class);

 private boolean runFlag = true;

 public Selector sel = null;

 public ServerSocketChannel server = null;

 public SocketChannel socket = null;

 private String ip = "127.0.0.1";

 private int port = 7008;

 public InterfaceDataControlCenterServer() {
  // default port
 }

 public InterfaceDataControlCenterServer(String ip, int port) {
  // another port
  this.ip = ip;
  this.port = port;
 }

 public void initializeOperations() throws IOException, UnknownHostException {
  sel = Selector.open();
  server = ServerSocketChannel.open();
  server.configureBlocking(false);
  // InetAddress ia = InetAddress.getLocalHost();
  log.info("IDCC Server Address: " + ip + " " + port);
  InetSocketAddress isa = new InetSocketAddress(ip, port);
  server.socket().bind(isa);
 }

 public void startServer() throws IOException {
  initializeOperations();
  SelectionKey acceptKey = server.register(sel, SelectionKey.OP_ACCEPT);

  while (acceptKey.selector().select() > 0) {

   Set readyKeys = sel.selectedKeys();
   Iterator it = readyKeys.iterator();

   while (it.hasNext() && runFlag) {
    SelectionKey key = (SelectionKey) it.next();
    it.remove();

    if (key.isAcceptable()) {
     ServerSocketChannel ssc = (ServerSocketChannel) key
       .channel();
     socket = (SocketChannel) ssc.accept();
     socket.configureBlocking(false);
     // SelectionKey another =
     socket.register(sel, SelectionKey.OP_READ);
    }
    if (key.isReadable()) {
     String ret = readMessage(key);
     if (ret != null && ret.length() > 0) {
      requestDispatcher(socket, ret);
     }
    }
   }
  }
 }

 public void requestDispatcher(SocketChannel socket, String ret) {

  try {
   log.info("IDCC Server catch a sign:" + ret.toString());
   log.info("IDCC Server Processing is completed.");
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 public String readMessage(SelectionKey key) {

  String result = null;
  int[] idccFlag = { 0, 0, 0, 0, 0 };
  int t = 0; // myByte step
  int k = 0; // IDCC Flag step
  int b = 0; // buf.get()

  boolean msgEndFlag = false;
  boolean msgBeginFlag = false;

  socket = (SocketChannel) key.channel();
  ByteBuffer buf = ByteBuffer.allocate(1024);
  byte[] myByte = new byte[1024];

  try {
   while (socket.read(buf) > 0 && !msgEndFlag) {
    buf.flip();
    if (buf.limit() == 0) {
     break;
    }
    while (buf.hasRemaining()) {
     if (!msgBeginFlag) {
      // msg Beign flag
      if (idccFlag[0] == 73 && idccFlag[1] == 68
        && idccFlag[2] == 67 && idccFlag[3] == 67
        && idccFlag[4] == 91) {
       myByte[0] = (byte) idccFlag[0];
       myByte[1] = (byte) idccFlag[1];
       myByte[2] = (byte) idccFlag[2];
       myByte[3] = (byte) idccFlag[3];
       myByte[4] = (byte) idccFlag[4];
       t += 5;
       msgBeginFlag = true;
      } else {
       if (k == 5) {
        idccFlag[0] = idccFlag[1];
        idccFlag[1] = idccFlag[2];
        idccFlag[2] = idccFlag[3];
        idccFlag[3] = idccFlag[4];
        k = 4;
       }
       b = buf.get(); // get data
       idccFlag[k] = b;
       k++;
      }
     } else {
      // get msg body
      b = buf.get(); // get data
      myByte[t] = (byte) b;
      if (b == 93) { // msg end flag ]
       // decode
       result = new String(myByte, "UTF-8").trim();
       msgEndFlag = true;
       break;
      } else {
       t++;
      }
     }
    }
   }

  } catch (IOException ioe) {
   log.error(ioe);
  }
  return result;
 }

 public synchronized void run() {
  try {
   startServer();
  } catch (IOException ioe) {
   log.error(ioe);
  }
 }

 public void stopThread() {
  this.runFlag = false;
  try {
   sleep(5000);
   server.socket().close();
   server.close();
   sel.close();
  } catch (InterruptedException ie) {
   log.error(ie);
  } catch (IOException ioe) {
   log.error(ioe);
  }
 }

 public static void main(String args[]) {
  InterfaceDataControlCenterServer nb = new InterfaceDataControlCenterServer();
  try {
   nb.startServer();
  } catch (IOException e) {
   e.printStackTrace();
   System.exit(-1);
  }

 }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值