2013年2月28日星期四

【转】用OPTIONS方法实现Keep Alive

noiile@hotmail.com

在SIP应用中,假如用户在用SIP UA享受某种计时收费的业务,比如在线观看收费电视,突然死机,这时服务器不能得知任何关于用户设备死机的信息,计费服务仍在继续。

这显然是种不合理的情况,服务器必须实时的知道用户的状态,这种情况presence服务器也不一定能帮助解决问题。因为用户的SIP UA只有在改变状态的情况下才发PUBLISH消息到Presence Server,也就是说要等这个PUBLISH expired,服务器才能知道用户已经不在线了。但是用户无论发PUBLISH还是REGISTER,它的过期时间的设置都取决于用户的SIP UA,很多时候,用户会把这个时间设为10分钟,或更长。这就不能满足某些业务实时性高的要求。

 

很容易得出结论,对于某些实时性要求高的业务,比如IPTV Server,无论是REGISTER还是PUBLISH都不能解决问题。解决方案需要考虑以下几点:

1.         利用现有的SIP方法,并且不取决于用户SIP UA

2.         用户的SIP UA不必对此做任何特殊的处理。

3.         且时间控制取决于服务方,即Application Server或其他Server,因为不同的服务可能对时间精度要求不同。

 

很明显,如果Server周期的发一个SIP请求到终端,这个周期时间取决于该Server,如果用户的SIP UA有回response,则表示用户还是online,如果用户没有回response,那它就是offline的,Server可以终止该用户的服务。

但是,用什么SIP方法最合适呢?OPTIONS。因为RFC3261定义,所有的UA都必须支持OPTIONS方法,所以OPTIONS方法满足了上面提及的2点要求。而且OPTIONS方法简单,只是请求用户SIP UA的能力,不需要人机交互,与Dialog无关。所以,用OPTIONS方法来获知用户是否online再合适不过了。

 

其流程如下图:

摘自:http://blog.csdn.net/noiile/article/details/448152

【转】procedure of object(一个特殊的指针类型)

    理论:     //适用于实现不是某一特定过程或函数
          type 
               TNotifyEvent = procedure(Sender: TObject) of object; 
      首先:procedure 也是类型,可以理解为过程类型,定义过程的参数结构,而具体的实现可以动态赋值 
 onclick那样例子: 
     声明:  onclick= procedure(Sender: TObject,a :integer) of object;以后你就可以把TNotifyEvent作为过程用了,而不用考虑它实现什么功能,你想onclik  里用户写了什么,都是一样的 
        if assign(onclick) then 
          onclick; 
     这样只要TNotifyEvent可以执行,程序就去执行它,控件就是这样实现事件的 
     procedure 指针占4个字节,保存在过程的地址. procedure of object占8个字节,保存过程的地址和类的地址 
     procedure of object 是类过程(类函数),用法如下: 
         1、与普通函数相同点:可以像一般的函数和过程一样在类的实例里作为对象方法调用; 
         2、与普通函数不同点:可以不通过对象,而是通过类来直接调用。 
    也就是说,一般函数和过程必须通过类的实例(对象)来调用,而类过程(类函数)则可以不必通过该类的实例来调用。通过类来调用函数或者过程,可以定义和实现一些不能或者不适合作为某一特定对象行为的方法。 
  应用:
     delphi中经常见到以下两种定义 
     Type 
         TMouseProc = procedure (X,Y:integer);  //一种普通的过程
         TMouseEvent = procedure (X,Y:integer) of Object;//一种对象方法的类型 

      两者样子差不多但实际意义却不一样,两者的区别就在于TMouseEvent类型的方法必须在一个对象里。类方法存在一个隐藏参数self,也就是说两者形参不一样,所以不能相互转换 .
   TMouseProc只是单一的函数指针类型; 
   TMouseEvent是对象的函数指针,也就是对象/类的函数/方法 
 procedure   TForm1.BBB(I:   Integer); 
begin 
    showmessage( 'BBB: '   +   IntToStr(I)); 
end; 

procedure   TForm1.CCC(I:   Integer); 
begin 
    showmessage( 'CCC: '   +   IntToStr(I)); 
end; 

procedure   TForm1.Button1Click(Sender:   TObject); 
    type 
        Taaa   =   procedure   (i:integer)   of   object   ; 
var 
    ap:   Taaa; 
begin 
    ap   :=   BBB; //这里有一个隐含Self,完整格式: self.BBB;这里把BBB这个方法赋给ap这个变量,注意BBB与ap的声明原型要一样,不然会有错
    ap(1); 
    ap   :=   CCC; 
    ap(2); 
end;

【转】Delphi 中的 procedure of object

其实要了解这些东西,适当的学些反汇编,WINDOWS内存管理机制,PE结构,看下李维的VCL架构剖析可以很好理解
type
  TMyEvent = procedure of object;
这是一种数据类型的定义,他定义了一个可以在类中使用的函数类型
区别于
type
  TMyProc = procedure;

TMyEvent 和 TMyProc 都定义了一个函数类型,他们的差别是,TMyProc 不可以用在类中定义事件,TMyEvent 却可以。

如果你想知道问什么,那就需要深入了解事件类型以及函数类型到底是个什么?

procedure a();
begin
  ShowMessage()
end;

var
  Func1: TMyProc;
  Func2: TMyEvent;

  func1 := A;

func1 := A;

这句到底发生了什么事情呢?

在32位的windows操作系统中,任何一个进程被执行,操作系统要完成的工作基本上包括:为这个进程开辟一个线性的虚拟地址表(从$00000000到$FFFFFFFF),然后把exe程序加载到这个地址表对应的内存中,然后跳入到exe程序的入口点,剩下的事情,就是exe自己从入口点开始一步一步干自己的事情了。
程序中,所有的函数都被编译到固定的位置,也就是每个函数都有一个地址与之对应,对函数的调用,实际上就是在寄存器或者堆栈中准备好参数,然后跳入到函数对应的地址继续执行。
func1 := A;
这个动作,完成的就是把函数A的地址赋值给func1这个变量。


那么,为Func2: TMyEvent 赋值又是完成了什么呢?

类中的函数也是有地址的,编译后,类中的函数也会被编译到一个固定的地址上。
但是,func2不是表示一个函数地址,他是一个记录类型的变量
这个可以通过 SizeOf(TMyEvent) 看到 SizeOf(TMyEvent) 返回值是8,而SizeOf(TMyProc)返回的是4
实际上,TMyEvent类型是包含两个域的一个记录,其中一个域是Code,也就是和TMyProc一样的,另一个域是Data,他保存着一个对象。

  Button2.OnClick := Button1Click;
这样的赋值,实际上是将窗体类的对象form1给data域,将Button1Click这个函数的地址给Code域

1.
TMyEvent = procedure of object; TMyEvent 是方法类型 就等于 String 是一种数据类型

如在一个Txxx类中定义了一个过程  
procedure Txxx.test;
begin
  showmessage('1');
end;

那么就可以把 Txxx.test 赋给 TMyEvent 了 (TMyEvent := Txxx.test);
因为 TMyEvent 的定义中有 of object 所以赋值给它的只能是类中的过程,而不能是普通过程。

2.
FOnHundred: TMyEvent; --> FOnHundred 是一个变量 它的类型是 TMyEvent,  
  就等于 icount : integer 这么简单

3.
property OnHundred: TMyEvent read FOnHundred write FOnHundred

OnHundred 是一个属性 它的类型也是 TMyEvent 通过 FOnHundred 变量来存取 这个属性的值。

当属性不用过程去存取的时候 (如上例)调用 OnHundred 和 FOnHundred 是相同的
 

delphi中经常见到以下两种定义

Type

TMouseProc = procedure (X,Y:integer);

TMouseEvent = procedure (X,Y:integer) of Object;

两者样子差不多但实际意义却不一样,

TMouseProc只是单一的函数指针类型;

TMouseEvent是对象的函数指针,也就是对象/类的函数/方法

区别在于类方法存在一个隐藏参数self,也就是说两者形参不一样,所以不能相互转换。

这也就是为什么delphi中可以这样赋值 button1.onClick:=button2.onClick;

却不能这样赋值 button1.onclick=buttonclick; (buttonclick为本地函数,button2.onclick为类方法)的原因!


方法类型定义:TMethod = procedure of object;

 

Procedural types allow you to treat procedures and functions as values that can be assigned to variables or passed to other procedures and functions. For example, suppose you define a function called Calc that takes two integer parameters and returns an integer:

function Calc(X,Y: Integer): Integer;

You can assign the Calc function to the variable F:

 

var F: function(X,Y: Integer): Integer;

F := Calc;

If you take any procedure or function heading and remove the identifier after the word procedure or function, what’s left is the name of a procedural type. You can use such type names directly in variable declarations (as in the example above) or to declare new types:

Type

TIntegerFunction = function: Integer;

TProcedure = procedure;

TStrProc = procedure(const S: string);

TMathFunc = function(X: Double): Double;

Var

F: TIntegerFunction;{ F is a parameterless function that returns an integer }

Proc: TProcedure;   { Proc is a parameterless procedure }

SP: TStrProc;       { SP is a procedure that takes a string parameter }

M: TMathFunc;       { M is a function that takes a Double (real) parameterand returns a Double }

procedure FuncProc(P: TIntegerFunction);  { FuncProc is a procedure whose only parameter is a parameterless integer-valued function }

The variables above are all procedure pointers—that is, pointers to the address of a procedure or function. If you want to reference a method of an instance object (see Classes and objects), you need to add the words of object to the procedural type name. For example

Type

TMethod = procedure of object;

TNotifyEvent = procedure(Sender: TObject) of object;

These types represent method pointers. A method pointer is really a pair of pointers; the first stores the address of a method, and the second stores a reference to the object the method belongs to. Given the declarations

Type

TNotifyEvent = procedure(Sender: TObject) of object;

TMainForm = class(TForm)

procedure ButtonClick(Sender: TObject);

...

end;

var

MainForm: TMainForm;

OnClick: TNotifyEvent

we could make the following assignment.OnClick := MainForm.ButtonClick;

Two procedural types are compatible if they have the same calling convention,the same return value (or no return value), and the same number of parameters, with identically typed parameters in corresponding positions. (Parameter names do not matter.)

Procedure pointer types are always incompatible with method pointer types. The value nil can be assigned to any procedural type.

Nested procedures and functions (routines declared within other routines) cannot be used as procedural values, nor can predefined procedures and functions. If you want to use a predefined routine like Length as a procedural value, write a wrapper for it:

function FLength(S: string): Integer;

begin

Result := Length(S);

end;

最后给大家个例子:
type
  TNotifyEvent = procedure(Sender: TObject) of object;
  TMainForm = class(TForm)
    procedure ButtonClick(Sender: TObject);
    ...
  end;
var
  MainForm: TMainForm;
  OnClick: TNotifyEvent
 
im.....

OnClick := MainForm.ButtonClick;

2013年2月27日星期三

【转】Delphi中如何检测本机UDP服务端口是否被占用

核心提示:判断某个UDP端口是否已被其他程序占用...
Program TestPort; 

uses 
  WinSock,windows; 

var 
  s : TSocket; 
  wsd : TWSAData; 
  SockAddrIn : TSockAddrIn; 
begin 
  if (WSAStartup(MAKEWORD(2,2),wsd) = 0) then 
  begin 
    s := Socket(AF_INET,SOCK_DGRAM,0); 
    try 
      if (s <> SOCKET_ERROR) then 
      begin 
        SockAddrIn.sin_family := AF_INET; 
        SockAddrIn.sin_addr.S_addr := htonl(INADDR_ANY); 
        SockAddrIn.sin_port := htons(Short(2222)); 
        if (Bind(s,SockAddrIn,SizeOf(SockAddrIn))<>0) then 
          if (GetLastError = WSAEADDRINUSE) then 
            MessageBox(0,'Port 2222 Be Using!','Sorry',MB_OK); 
      end; 
    finally 
      CloseSocket(s); 
      WSACleanup(); 
    end; 
  end;

2013年2月26日星期二

【转】Js/Jquery获取iframe中的元素 在Iframe中获取父窗体的元素方法

在web开发中,经常会用到iframe,难免会碰到需要在父窗口中使用iframe中的元素、或者在iframe框架中使用父窗口的元素

js

在父窗口中获取iframe中的元素 

1、

格式:window.frames["iframe的name值"].document.getElementByIdx_x("iframe中控件的ID").click();

实例:window.frames["ifm"].document.getElementByIdx_x("btnOk").click();

2、

格式:

var obj=document.getElementByIdx_x("iframe的name").contentWindow;

var ifmObj=obj.document.getElementByIdx_x("iframe中控件的ID");

ifmObj.click();

实例:

var obj=document.getElementByIdx_x("ifm").contentWindow;

var ifmObj=obj.document.getElementByIdx_x("btnOk");

ifmObj.click();

在iframe中获取父窗口的元素

格式:window.parent.document.getElementByIdx_x("父窗口的元素ID").click();

实例:window.parent.document.getElementByIdx_x("btnOk").click();

jquery

在父窗口中获取iframe中的元素 

1、

格式:$("#iframe的ID").contents().find("#iframe中的控件ID").click();//jquery 方法1

实例:$("#ifm").contents().find("#btnOk").click();//jquery 方法1

2、

格式:$("#iframe中的控件ID",document.frames("frame的name").document).click();//jquery 方法2

实例:$("#btnOk",document.frames("ifm").document).click();//jquery 方法2

在iframe中获取父窗口的元素

格式:$('#父窗口中的元素ID', parent.document).click();

实例:$('#btnOk', parent.document).click();

摘自:http://blog.sina.com.cn/s/blog_732478620100wuha.html

2013年2月25日星期一

【转】jquery 获取iframe里的元素的值|jquery给父页传值

摘自:http://hi.baidu.com/tieniu116/item/4fe8541eff15c3f087ad4e39


ifram子页元素

<a href="javascript:add();"
class="red" id="add">| 上传文件</a>

1、在子页申明方法

function add() {
var this_path = $('#path a:last').attr('href').substring(6);//此处可以用jquery获取子iframe的元素
parent.add(this_path);
}

2、父页方法

function add(this_path) {

alert(this_path)

}

本文首发地址:http://www.52hudie.com/item_10770.html