• 螳螂和信史

    2004-03-10

    Tag:技术

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://samhoo.blogbus.com/logs/116634.html

    背景

    .螳螂--mantis
    mantis是一个小巧而功能较为齐备的缺陷跟踪管理开源软件,目前最新版本是0.18.2()。DW有介绍有篇很好的介绍文章(http://www-900.ibm.com/developerWorks/cn/linux/software_engineering/l-mantis/index.shtml),这里就不在罗嗦。

     
    图1:mantis的bug录入界面。

    .信史--IPMessenger
    信史是一个日本人编写的即时消息通讯软件,适合用于局域网内甚至广域网内进行实时通讯和共享文档,仅需要TCP/IP和UDP支持,有多种操作平台下的版本,不需要服务器端软件。特点是界面简洁,功能强大,传送的数据采用RSA/Blofish算法进行加密,可以方便快捷的传送文件和文件夹,并记录通讯消息日志。(这是某软件站点关于改软件的介绍,简明扼要,摘抄于此)

    图2:IPMesseger

    mantis提供了一项很有用的功能:bug在生命周期中,当其状态发生变化时(如,某个bug经管理者审定后派发给某个开发人员),将状态变更通过邮件通知相关人员。不幸的是,IPMessenger由于它的简单易用、稳定,在我们的团队以及客户中受到了广泛的欢迎,成为项目组中的重要的即时沟通工具。而邮件客户端(如OutLook Express),由于所在的开发环境Internet接入能力较差,并未得到广泛使用。为了能即时将bug通知相关人员,而且适应目前的开发环境,我想到,应该修改mantis的邮件通知功能为IPMessenger通知。

    准备

    1)下载安装mantis的运行环境:Apache + PHP + mysql,我用的版本是:Apache1.3 + php-4.3.4 + mysql 4.0.12,至于安装过程不是本文的范围,各位可以在网上找到相当丰富的资源。
    2)下载mantis, 安装mantis也相当的简单,这里有一篇文章可以参考:http://hedong.3322.org/archives/000263.html
    3)下载windows版本的IPMesseger(绿色软件,无需安装汉化后名字变为“飞鸽传书”,随处可down),而且还要去其项目网站(英文版:http://www.asahi-net.or.jp/~VZ4H-SRUZ/ipmsg-eng.html,日文看不懂:)下载一个java实现,很简陋,对吗?没关系,我们后面的改造根本不用它的gui界面。


    改造思路

    为了使mantis能支持ipmessenger通知,有三种方法:
    1)通过分析IPMessenger的代码(java实现或是VC实现也好),用PHP实现其协议,并修改相应的mantis邮件通知代码。
    2)稍加修改IPMessenger的java实现,通过PHP提供的java集成模块,直接使用java的代码。
    3)修改IPMessenger,使其支持转发模式(为了方便说明,下面简称为EXIPMsg)。也就是说mantis只需发一个简单的UDP包给EXIPMsg,由EXIPMsg负责转发。

    IPMessenger虽小,但五脏俱全:配置文件的读写,握手协议(包含交换公钥,签到,离开等握手状态)、消息传送应答、加解密。第一种方法开发显然开发量不小。第二种方法听起来确实很省事,但不幸的是:PHP的java集成模块在Apache下并不可用(据说在支持线程的IIS可用),总是在第二次调用java代码时,无法再次启动java虚机。第三种方式之所以想到转发,是因为通过EXIPMsg,mantis和EXIPMsg之间只需要一种简单的协议命令,而EXIPMsg和IPMessenger之间照样维持较为复杂的协议。这样,通过中间的EXIPMsg可以避免实现IPMessenger较为复杂的协议。PHP部分增加简单的UDP代码即可,而且效率非常高。所以下面的工作主要围绕的这一目标进行,同时为了以后java应用也能集成这IPMessenger的功能,我也增加了封装IPMessager的一些代码。下面最终实现后的命令行用法,先列出来,有助于理解改造思路。

    Usage:   [no argument]                           Start ipmsg in GUI mode       
             -d                                      Start ipmsg in deamon mode
             -s ipaddresss[,ipaddress] -m message    Send a message to a ip address list
                                                                                      
    Example: java -jar Main -s 192.168.1.33 "hello, ipmsg\"       
             java -jar Main -s 192.168.1.33,92.168.1.34 "hello, ipmsg"            


    源码分析

    .IPMessenger
    的源码包很简单,分为三个部分:缺省包,ipmsg, JP。缺省包中主要是Main类和关于gui的类,ipmsg是协议的实现,JP是一些util类。重点在实现ipmsg包中,今晚时间无多,就不分析各个类之间的关系,仅列出分析过程中写下的握手协议备忘:
    IPMsg握手协议:                     
        A:发送广播,内容:nick name,命令:IPMSG_BR_ENTRY(广播自己的信息)
        B:收到广播包,发送回应,内容:自己的nick name, 命令:IPMSG_ANSENTRY(回应自己的信息)
        A:收到回应,发送回应,内容:自己的公钥,命令:IPMSG_GETPUBKEY(请求对方公钥)
        B:收到回应,发送回应,内容:自己的公钥,命令:IPMSG_ANSPUBKEY(返回公钥)
        A:收到回应,记录公钥。握手结束。
    接下来就是正常的消息发送/应答,还有其它一些协议命令,这些协议命令的的控制,都是在IPMsg.java中完成。

    .mantis
    mantis的分析就更简单,这里不再罗嗦:在mail_api.php的mail_send函数负责发送邮件通知,修改即可。


    源码修改
    .IPMessenger
    这里我把修改过程中记录的ChangLog贴上:
    ipmsg_api.php:
     . 2004/03/08 实现PHP接口函数,通过UDP向ipmsg转发服务器发送消息。

    Main.java
     . 2004/03/07 修改main方法,保留原有GUI模式外,增加另外两种模式:1)转发守护进程模式 2)直接发送消息模式
     . 2004/03/07 增加send(String AddressList, String Message)方法,作为ipmsg的开发接口;
    ipmsg/IPMsg.java:
     . 2004/03/02 修改entry()
     . 2004/03/02 增加prepareUDPDeamon()方法,由原entry()方法剥离出来
     . 2004/03/02 增加entryAll()方法,用于广播握手,等同于原来的entry();
     . 2004/03/02 增加entry(IPMAddress [])方法,用于发送前定点(即已知地址)握手
     . 2004/03/07 增加IPMSG_FORWARD命令
     . 2004/03/07 修改recieve(),支持IPMSG_FORWARD命令,用于转发消息
     . 2004/03/02 修改encryptMessage(String),decryptMessage(String )方法,将编码方式由SJIS改为GBK,支持中文。
     . 2004/03/07 增加messageIPMRecv 变量,修改exit()方法,修复“退出后不终结2425监听线程bug"
    ipmsg/IPMPack.java:
     . 2004/03/02 将编码方式由SJIS改为GBK,支持中文

    .mantis
    增加发送EXIPMsg报文的函数:ipmsg_send,修改mail_send函数即可,下面是ipmsg_send函数:
    <?php
    function ipmsg_send($forward_host_addr, $desc_host_addr, $message)
    {
     $s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
     if ($s == false)
      {
       echo "Error creating socket!\n";
       echo "Error code is '".socket_last_error($s)."' - " . socket_strerror(socket_last_error($s));
      }
     else
     {
      $version = '1';
      $time_stamp = time().rand(1,1000);
      $nickname = 'mantis';
      $groupname = 'mantis';
      $port = 2425;
      $msg = $version.":".$time_stamp.":".$nickname.":".$groupname.":129:".$desc_host_addr.":".$port.":".$message;
      $e = socket_sendto($s, $msg, strlen($msg), 0, $desc_host_addr, $port);
      socket_close($s);
      echo "Magic Packet sent (".$e.") to ".$addr." time stamp=".$time_stamp." msg=".$msg;
     }
    }
    ?>


    后记
    如同预期的一样,当bug的状态发生变更时,相关的人员就可以及时的得到通知,如下图。但是这只是一个简单的探索性实验,如果要真正使用仍然需要考虑其它一些问题:修改mantis中的人员住册信息(增加其使用的机器名或地址);对IPMSG_FORWARD协议命令的响应,以判断是否发送成功,否则再发送邮件;当bug变更相当频繁时(如集成测试开始阶段),允许设置几条bug状态才发送一次...,由于上述尝试都是在业余时间做的,这些考虑将会慢慢的实现。如果你有兴趣,也可以联系我讨论。fxh@263.net  MSN:samhoovon@hotmail.com;

    图3:当bug报告人员录入一个新的bug的时候,相关人员就可以得到这样的即时通知


    收藏到:Del.icio.us




    引用

    下面Blog引用了该文:

    评论

  • vfiet qknv yerovqt xofcsjuy bpfuy ibvmqwc unstxomh
  • zekmucwbs zbfptwi qbed fhdwm jdyxtqlku xqulr jskygwb