qq的离线消息功能是怎么做出来的,我看了几天也没搞定,能说详细点吗,

解决方案 »

  1.   

    gardenyang(太阳雨) 的可以,
    还有吗
      

  2.   

    解决“登陆的时候自动从数据库中读出来”,是不是要用到datasnap技术,我不知道,
    请说明
      

  3.   

    //以前自己学着玩作的,代码很乱
    客户端
    procedure TForm2.SpeedButton4Click(Sender: TObject);
      var //sendtxt: Array [1..50] of Char;
          A: array[0..2047] of Char;
          ini_calstr:string;
          now_time:ansistring;
          //txt:pchar;
    begin
         if Memo2.Text='' then
          begin
           application.MessageBox('不能发送空消息!','注意',MB_OK);
           exit;
          end;
         now_time:=DateTimeToStr(Now);
         if Edit4.Text<>'' then //用户在线就点对点发送
       begin
        SendMessage(self.Handle,WM_SYSCOMMAND,SC_MINIMIZE,0);
        form1.NMUDP2.ReportLevel := Status_Basic;
        form1.NMUDP2.RemoteHost:=edit4.Text;
        form1.NMUDP2.RemotePort:=20000;//20001;
        //form1.NMUDP1.LocalPort:=6668;//20000;
        StrPCopy(A, edit1.Text+'&'+edit2.Text+'&'+edit4.Text+'&'+memo2.Text);
        form1.NMUDP2.SendBuffer(A,2048);
        //form1.NMUDP1.RemotePort:=20000;//20001;
        //form1.NMUDP1.LocalPort:=20001;//20000;
        end
       else begin             //用户不在线就发送到服务器端数据库保存起来
            try
            adoquery1.Close;
            adoquery1.ConnectionString:='';
            adoquery1.Connection:=form1.ADOConnection1;
            adoquery1.SQL.Clear;
            adoquery1.SQL.Add('insert into message values('''+edit1.Text+''','''+form1.Caption+''','''+Now_Time+''','''+memo2.Text+''',1)');
            adoquery1.ExecSQL;
            except
            end;
            adoquery1.Close;   end;
       //同时保存一份到本地数据库 
       try
        adoquery2.Close;
        ini_calstr:=form1.appPath+'\\'+form1.Caption;
          adoquery2.ConnectionString:='Provider=MSDASQL.1;Persist Security Info=False;Data Source=dBASE Files;Initial Catalog='''+ini_calstr+'''';
          adoquery2.SQL.Clear;
          adoquery2.SQL.Add('insert into mesdata values('''+edit1.Text+''','''+edit2.Text+''','''+now_time+''','''+memo2.Text+''')');
          adoquery2.ExecSQL;
        except
        end;
          adoquery2.Close;
        //freemem(txt);
        //hide;
        close;
    end;服务器端
    procedure TForm1.Timer1Timer(Sender: TObject);
    var  A: array[0..2047] of Char;
         I:integer;
         SndNumbers:ansistring;
    begin
        //每隔3秒检测用户在线用户是否有消息,有则发出去并在数据库中删除记录
        try
        adoquery2.SQL.Clear;
        adoquery2.SQL.Add('select message.发送号码,users.当前ip,users.昵称,message.接收号码,message.发送时间,message.发送内容,message.消息类型 from users,message where users.号码=message.接收号码 and users.状态=''online'' order by 接收号码');
        adoquery2.Open;
        except
        end;
        NMUDP1.RemotePort:=20000;
        //NMUDP1.LocalPort:=20001;
        while not adoquery2.Eof do
           begin
             if adoquery2.FieldByName('消息类型').AsInteger=1 then //不是系统信息
                 StrPCopy(A,adoquery2.FieldByName('发送号码').AsString+'&'+adoquery2.FieldByName('昵称').AsString+'&'+adoquery2.FieldByName('当前ip').AsString+'&'+adoquery2.FieldByName('发送时间').AsString+'&'+adoquery2.FieldByName('发送内容').AsString )
             else
                 StrPCopy(A,'@'+adoquery2.FieldByName('发送号码').AsString+'@'+adoquery2.FieldByName('昵称').AsString+'@'+adoquery2.FieldByName('当前ip').AsString+'@'+adoquery2.FieldByName('发送内容').AsString );
             NMUDP1.RemoteHost:=adoquery2.FieldByName('当前ip').AsString;
             NMUDP1.SendBuffer(A,2048);
             SndNumbers:=SndNumbers+adoquery2.FieldByName('接收号码').AsString+',';
             adoquery2.Next;
           end;
          adoquery2.Close;
          SndNumbers:=copy(SndNumbers,0,length(SndNumbers)-1);
        {  try
          adoquery2.SQL.Clear;
          adoquery2.SQL.Add('delete from message where 发送号码 in('+SndNumbers+')');
          adoquery2.ExecSQL;
          adoquery2.Close;
          except
          end; }
    end;procedure TForm1.Timer2Timer(Sender: TObject);
    begin
       //每隔3分钟刷新在线状态
        try
        adoquery3.SQL.Clear;
        adoquery3.SQL.Add('update users set 状态=''offline''');
        adoquery3.ExecSQL;
        adoquery3.Close;
        except
        end;
    end;
      

  4.   

    OICQ利用的是Socket5通信方式。它上线时先从服务器取回好友信息和在线状态,发送超时还会将信息先保存在服务器,等对方下次上线后再发送然后把服务器的备份删除。可以再添加一个NMUDP控件来管理在线状态