精华内容
下载资源
问答
  • 研究了一下怎么加css、js,网上的好多资料都是在框架根目录下的第一层有css、js文件夹,大家觉得不利于协同开发时各人自扫门前雪的特质,想在各自的module下维护一套,没想到的是,这样的情况下registerCssFile等...
    1. 研究了一下怎么加css、js,网上的好多资料都是在框架根目录下的第一层有css、js文件夹,大家觉得不利于协同开发时各人自扫门前雪的特质,想在各自的module下维护一套,没想到的是,这样的情况下registerCssFile等函数失效了,大概意思是protected下边的东西不允许访问,当然了,我也不太明白为什么,也不确定是否是我哪里没设置对。但是本着解决问题的精神,发现assets是个好东东。我们可以使用如下代码自由加载css等到asset文件夹下,可以选择单个文件、某个文件夹下的所有子文件夹等方式进行加载,而且这种加载方式可以避免重复加载,节省资源。
    $cs=Yii::app()->clientScript;
    $cssDir=Yii::getPathOfAlias("access.css") ;
    $published = Yii::app()->assetManager->publish($cssDir);
    	$cssFile = $published . "/" . "homemain.css";
    	if (!Yii::app()->clientScript->isCssFileRegistered($cssFile)) {
    	   Yii::app()->clientScript->registerCssFile($cssFile);
    	} ?>
    2. 上面用到的assetmanager是/web/CAssetManager.php中描述的,其中publish函数有如下参数:$path:css等文件的位置,$hashByName是否对在assets文件夹下生成的资源文件夹进行哈希,$level加载方式(单文件、文件夹全加载神马的),$forceCopy是否强制每次都重新加载(个人认为css调试的时候用比较好,否则修改过的css可能因为不重新加载而不能立即生效)。综上所述,很简单的,js、image同理。
    3.  
    //在底部加载自定义JS
    Yii::app()->clientScript->registerScriptFile("xxx",CClientScript::POS_END); 


    展开全文
  • 如何将自己做的网页发布到网站让别人可以看到

    万次阅读 多人点赞 2018-09-18 20:32:13
    自从在大学学了H5之后,一直都在想,怎么将自己写的HTML网页发布到网上像百度一样让任意用户可以访问呢?于是我便做了一些尝试,并有了如下收获: 首先,网站上传到网站让别人访问需要以下东西: 1:域名 2:...

           自从在大学学了H5之后,一直都在想,怎么将自己写的HTML网页发布到网上像百度一样让任意用户可以访问呢?于是我便做了一些尝试,并有了如下收获:
           首先,把网站上传到网站让别人访问需要以下东西:

     1:域名
     2:空间
           什么是域名呢?域名可以理解为一个地址,就好baidu.com, sina.cn这些简称为域名,域名分为一级、二级、三级以及四级域名,如:Baidu.com,这种就是域名,www.baidu,com这种就是二级域名,www.youhua.baidu.com就是三级域名,以多少个点来区别为几级域名。
          什么是空间呢?简单来说,就是存放网站内容的地方。这两者缺一不可,如果只有baidu.com这个域名没有空间的话你访问baidu.com就会什么都没有,而只有空间没有域名,你都无法访问。
           通常买了域名和空间后会进行解析和绑定,解析就是把域名指向到空间的IP地址上面(买了空间会有一个IP地址),而空间那边需要绑定。

           其次,申请域名可到腾讯云里操作;申请成功后记得进行域名解析。购买空间可到凡科网里操作。

           然后,域名绑定空间:

     要使域名和空间绑定起来,先要将域名解析到服务器,绑定服务器的IP地址。

    方法一:在注册空间时绑定域名,注册空间时提示域名,录入要绑定的域名,在“我已阅读并接受虚拟主机租用协议”前的框中勾选,再点击确认进行确定申请开通空间。

    方法二:除注册空间时绑定域名的方式外,还有在空间面板里绑定域名——打开空间管理的控制面板,找到域名绑定一项,点击打开(注意不管是买的什么空间,管理面板都域名绑定这一功能)。在添加域名后的录入框里录入域名地址,再点击添加绑定,进行绑定确认操作。

        接着,绑定完之后,我们就开始把自己的东西上传到空间了,然后通过域名就可以访问啦:
        我们需要下载一个软件,百度一下FTP ,会有很多FTP软件,至于什么是FTP.,我们可以把它理解为一种传输协议,把本地文件传到空间的一种工具,这里我们用8UFTP为列,我们打开软件, 详见下图:

           登录成功后,我们可以看到右边用红色框起来的部分,那个部分就是存放网站内容的目录,默认是根目录,一般会有两个目录,一个存放网站内容,一个存放数据库。此后,我们就可以把自己的网页传进去了。在左边目录选中需要上传的文件右键选择上传就行了!!!

     

    参考链接:服务器运用之——云服务器Ubuntu或者CentOs搭建JavaWeb环境

    展开全文
  • 我想大多数朋友刚开始做网站开发不久,都会想自己的项目上传到网上,可以让自己用域名来搜索自己的网站,但是却不知道怎么做,一般我们都要用到 “云服务器”,“域名”,“云主机”这些东西。 这次我只能和大家...

    我想大多数朋友刚开始做网站开发不久,都会想把自己的项目上传到网上,可以让自己用域名来搜索自己的网站,但是却不知道怎么做,一般我们都要用到 “云服务器”“域名”“云主机” 这些东西。

    这次我只能和大家说说这些东西的关系,和用法还有自己的理解,主要是让大家了解了解,知道自己应该买什么,至于上传我也是刚刚弄出来。后面有时间我会和大家详细解说;


    首先,第一个我来说说 “域名”:

    "域名"比较简单,就是我们常说的 “网址” ,例如:www.baidu.com;  mp.csdn.net;  这些,我们都是通过这个来搜索我们自己的网站,所以也就像是一个导游一样,引领你来到你在网上储存的空间的一个东西

    其次,我来说说 “云主机”:

    相对于  "域名"  云主机就是域名最终要到的地方了,“云主机” 就是在网络上面开辟了一个空间,用来储存自己上传的网站,从而通过 “域名”  来到自己的项目下,找到你项目目录的  index.html文件,然后进行访问,“云主机”只能认识项目根目录下的index.html为首页。

    但是,但是,但是,重要的事情说三遍,目前我看了很多平台,云主机也就只能支持PHP语言的动态网站享目,和纯静态网站享目

    可以支持其他语言的我暂时没有找到。

     最后,我来说说 “云服务器”

    “云服务器”也是最重要的一个,大部分人的项目都是应该会用这个来上传。因为  “云服务器”  你就可以理解为一台虚拟的电脑,

    例如:你要上传一个用java写的javaweb项目,但是“云主机”并不支持java语言,这个时候你就不能用这个上传你的项目了,你就需要用“云服务器”来上传你的项目,然后你需要在服务器上面来搭建Java环境,就和你在自己的电脑上创建Javaweb项目一样,首先配置jdk,然后配置tomcat,最后如果是动态网站的话,就安装mysql,应为 “云服务器”本身就是有操作系统的,一般都是用Linux的,所以只是操作系统换了,做法都是一样的。

    最后如果你买了服务器之后,会有一个公网ip,用这个ip就可以直接访问你的网站了,如果你想通过域名来访问,就需要将这个ip和你的域名解析,才可以。

    这次的博客并没有实质的告诉大家应该怎么上传,因为有很多人并不知道应该怎么上传,到了百度云,阿里云,腾讯云这些网页,看到很多,什么云数据库,云主机,云服务器,不知道改怎么选,这个我就是告诉大家,让大家了解了解,才能少花冤枉钱。 

    展开全文
  • 计算机网络培训总结怎么写 计算机网络培训总结怎么写?下面小编整理了计算机网络培训总结,欢迎...而制作网页的知识,学了一点,也会做一些简单的网页了,其实我觉得这就够了,我还没有想做自己的网页发布到网上的念?..
  • 这篇东西原写在csdn.net上,最近新开通了博客想零散在各处的都转移一处。 一、源起 学WCF有一段时间了,可是无论是微软的WebCast还是其他网上的教程,亦或我购买的几本书中,都没有怎么提到服务器端事件的...
    这篇东西原写在csdn.net上,最近新开通了博客想把零散在各处的都转移到一处。
     
    一、源起 学WCF有一段时间了,可是无论是微软的WebCast还是其他网上的教程,亦或我购买的几本书中,都没有怎么提到服务器端事件的订阅。(后来购买的一本WCF服务编程中提供了关于订阅和发布的例子) 网上也查了很多,但大部分都没有清楚地讲到这部分内容,有的虽然是讲这部分内容,但也是语焉不详。最重要的部分都没有讲到(也许是因为水平太差,看不懂)。而且网上和书上所用的语言都是C#,这让人很恼火,虽然我能使用C#,但总是不如用了十几年的VB看起来顺眼。而且最关键的是C#关于委托和事件处理上和VB有着很大的不同。比如:在C#中,事件本质上就是委托,而且处理方式都一样。但在VB中事件和委托很多差别,尤其是在处理方式上。比如,VB中事件不能直接支持返回列表,虽然编译器提供了一个变形后的变量来提供支持,但和c#中的直接遍历还是差很多。所以在把C#代码转换成VB代码时,一遇到事件或委托就很难办,因为用的方法不同。直接把代码语法改掉是编译不过的。这让我着实忧闷了很久。因为写项目,一定会遇到订阅和发布的。 前几天在网上又搜索相关的文章,这次也许运气很好,找到了一篇讲事件广播的,是一个叫张玉彬的博客上的文章,文章名叫:WCF从理论到实践(8):事件广播 ,文章地址:http://www.cnblogs.com/jillzhang/archive/2008/02/24/1079339.html  。当然一点也不意外,这篇文章里面用的代码是C#(搞什么?VB没人用了吗?),最可心的是文章提供了例子代码。没什么好说的,把代码当回来,打开直接在VS中用VB重写一遍。。。。。所以,就有了这篇日志。呵呵。这样,也算是对自己这段时间学习WCF的一个小总结。如果能帮上哪位学VB朋友的忙的话那就最好不过了。呵呵。
    二、实例分析 1、这是一个微软培训教程中用过的一个例子。我记得在学习Remoting时学过这个项目。很简单的一个例子: 服务器上维护一个JOB List,客户端用来提交、执行JOB,服务器将JOB状态和结果通知给每个客户端。这样就必须实现客户端订阅服务端事件。看起来是这个样子的。其实,非网络的事件,我们知道是比较容易实现的。也就是自定义事件的问题。一直以来,我总以为客户端订阅服务器事件也象在单机程序中那样。但由于两端不在一个程序域内,所以无法实现事件在两端的传播。我曾试图把委托或事件做为数据契约(DataContract)来处理,结果大家都知道。委托根本就无法传递和准确序列化,而事件根本就不支持数据契约(后来在书看到,事件必须添加FiledData特性才能支持契约,而委托虽然支持契约,却无法实现正确序列化)。不废话了。 2、原文章部分  略。(运行部分截图也见上文提到 的文章,不管是不是原创,毕竟对我有很多帮助,就不抢别人功劳了。呵呵。) 三、我的代码 由于这个例子相当简单,再加上本人也没什么写文章的天赋,所以,话就不多说了。直接上代码。。。。  1、使用事件进行广播 1)项目用到的JOB类:
    1. <DataContract()>  
    2. Public Class job  
    3.     Private m_Name As String  
    4.     Private m_Status As String  
    5.     Private m_LastRunTime As DateTime  
    6.     Private m_LastRunResult As String  
    7.   
    8.     Public Sub New()  
    9.         Me.Status = "Sleeping"  
    10.         Me.LastRunResult = ""  
    11.     End Sub  
    12.   
    13.     <DataMember()>  
    14.     Public Property Name As String  
    15.         Get  
    16.             Return m_Name  
    17.         End Get  
    18.         Set(ByVal value As String)  
    19.             m_Name = value  
    20.         End Set  
    21.     End Property  
    22.   
    23.     <DataMember()>  
    24.     Public Property Status As String  
    25.         Get  
    26.             Return m_Status  
    27.         End Get  
    28.         Set(ByVal value As String)  
    29.             m_Status = value  
    30.         End Set  
    31.     End Property  
    32.   
    33.     <DataMember()>  
    34.     Public Property LastRunTime As DateTime  
    35.         Get  
    36.             Return m_LastRunTime  
    37.         End Get  
    38.         Set(ByVal value As DateTime)  
    39.             m_LastRunTime = value  
    40.         End Set  
    41.     End Property  
    42.   
    43.     <DataMember()>  
    44.     Public Property LastRunResult As String  
    45.         Get  
    46.             Return m_LastRunResult  
    47.         End Get  
    48.         Set(ByVal value As String)  
    49.             m_LastRunResult = value  
    50.         End Set  
    51.     End Property  
    52. End Class  
    2)项目中用到的回调接口
    1. <ServiceContract()>  
    2. Public Interface ICallback  
    3.     <OperationContract(IsOneWay:=True)>  
    4.     Sub StatusChanged(ByVal job As job)  
    5.   
    6.     <OperationContract(IsOneWay:=True)>  
    7.     Sub OnAdd(ByVal newJob As job)  
    8.   
    9.   
    10. End Interface  
    3)项目中用到的服务契约
    1. '<ServiceContract(SessionMode:=SessionMode.Required, CallbackContract:=GetType(ICallback))>  
    2. '不使用事件,只使用委托时,是否可以不用会话  
    3. '<ServiceContract(SessionMode:=SessionMode.Allowed, CallbackContract:=GetType(ICallback))>  
    4. <ServiceContract(CallbackContract:=GetType(ICallback))>  
    5. Public Interface IService  
    6.   
    7.     '<OperationContract()>  
    8.     'Function GetData(ByVal value As Integer) As String  
    9.   
    10.     '<OperationContract()>  
    11.     'Function GetDataUsingDataContract(ByVal composite As CompositeType) As CompositeType  
    12.   
    13.     ' TODO: 在此添加您的服务操作  
    14.     'IsInitiating 表示 是否可以在服务器上启动会话  
    15.     'IsTerminating 指示服务操作在发送答复消息(如果存在)后,是否会导致服务器关闭会话。  
    16.     <OperationContract(IsOneWay:=True, IsInitiating:=True, IsTerminating:=False)>  
    17.     Sub Accept()  
    18.   
    19.     <OperationContract(IsOneWay:=True, IsInitiating:=True, IsTerminating:=False)>  
    20.     Sub DoJob(ByVal jobName As String)  
    21.   
    22.     <OperationContract(IsOneWay:=True, IsInitiating:=True, IsTerminating:=False)>  
    23.     Sub AddJob(ByVal newJob As job)  
    24.   
    25.     <OperationContract(IsOneWay:=False, IsInitiating:=True, IsTerminating:=False)>  
    26.     Function GetJobs() As List(Of job)  
    27.   
    28.   
    29. End Interface  
    说明:按照 网上文章的说法,事件广播要使用到 会话。但实际上,会话在这里并不重要。这我在后面验证。 4)项目中的服务实现类 这里,要用到InstanceContextMode特性,因为项目在这时还要保持会话。
    1.   
     
    1. '<ServiceBehavior(InstanceContextMode:=InstanceContextMode.PerSession, ConcurrencyMode:=ConcurrencyMode.Multiple)>  
    2. '不使用事件,只使用委托,是否可以不用会话  
    3. '<ServiceBehavior(InstanceContextMode:=InstanceContextMode.Single, ConcurrencyMode:=ConcurrencyMode.Multiple)>  
    4. <ServiceBehavior(InstanceContextMode:=InstanceContextMode.Single, ConcurrencyMode:=ConcurrencyMode.Multiple)>  
    5. Public Class JobServerImplement  
    6.     Implements IService  
    7.   
    8.     Public Shared m_jobs As List(Of job) '用来返回 job列表  
    9.     Public Shared jobs_Lock As Object  '同步锁用  
    10.     '事件委托定义  
    11.     Public Delegate Sub JobServerEventHandler(ByVal sender As Object, ByVal e As JobCallbackEventArg)  
    12.   
    13.     '定义共享的 事件 列表  
    14.     Public Shared onChangeEvents As List(Of JobServerEventHandler)  
    15.     Public Shared onAddEvents As List(Of JobServerEventHandler)  
    16.   
    17.     '定义客户端 回调通道 列表  
    18.     Public Shared clientCallBackChannles As List(Of ICallback)  
    19.   
    20.   
    21.     'job状态改变事件定义,事件必须定义为 共享  
    22.     'Public Shared Event onJobStatusChanged As JobServerEventHandler  
    23.     Public Shared Custom Event onJobStatusChanged As JobServerEventHandler  
    24.         AddHandler(ByVal value As JobServerEventHandler)  
    25.             If jobs_Lock Is Nothing Then  
    26.                 jobs_Lock = New Object()  
    27.             End If  
    28.             If onChangeEvents Is Nothing Then  
    29.                 SyncLock jobs_Lock  
    30.                     onChangeEvents = New List(Of JobServerEventHandler)  
    31.                 End SyncLock  
    32.             End If  
    33.   
    34.             SyncLock jobs_Lock  
    35.                 onChangeEvents.Add(value)  
    36.                 Console.WriteLine("AddHandler Done!")  
    37.             End SyncLock  
    38.         End AddHandler  
    39.   
    40.         RemoveHandler(ByVal value As JobServerEventHandler)  
    41.             If onChangeEvents Is Nothing Then  
    42.                 Return  
    43.             End If  
    44.             SyncLock jobs_Lock  
    45.                 onChangeEvents.Remove(value)  
    46.                 Console.WriteLine("RemoveHandler Done!")  
    47.             End SyncLock  
    48.         End RemoveHandler  
    49.   
    50.         RaiseEvent(ByVal sender As Object, ByVal e As JobCallbackEventArg)  
    51.             For Each tmpH As JobServerEventHandler In onChangeEvents  
    52.                 tmpH.BeginInvoke(sender, e, Nothing, Nothing) ' New System.AsyncCallback(AddressOf EndAsync), Nothing)  
    53.   
    54.                 Console.WriteLine("RaiseEvent")  
    55.             Next  
    56.         End RaiseEvent  
    57.     End Event  
    58.   
    59.     'Public Custom Event   
    60.   
    61.     '内部事件传递 委托  
    62.     'Private MyChangeHandler As JobServerEventHandler  
    63.   
    64.     'job添加事件定义,事件必须 共享  
    65.     'Public Shared Event onAdd As JobServerEventHandler  
    66.     '内部事件传递委托  
    67.     'Private MyAddHandler As JobServerEventHandler  
    68.   
    69.     '回调 接口   
    70.     Dim callbackInterface As ICallback  
    71.   
    72.     '每一次回调,分开后,如果 哪个客户端失败,不会影响其他存在客户端  
    73.     Private Sub CallBackOnce(ByVal theCallBack As ICallback, ByVal e As JobCallbackEventArg)  
    74.         Try  
    75.             If e.ChangeReason = "Add" Then  
    76.                 Console.WriteLine("CallBackOnce reason: Add")  
    77.                 theCallBack.OnAdd(e.Job)  
    78.             Else  
    79.                 Console.WriteLine("CallBackOnce reason: Modi")  
    80.                 theCallBack.StatusChanged(e.Job)  
    81.             End If  
    82.         Catch ex As Exception  
    83.             Console.WriteLine("CallBackOnce Got Error:" & ex.Message)  
    84.         End Try  
    85.     End Sub  
    86.   
    87.     '不使用事件,直接使用委托来回调客户端  
    88.     Private Sub Server_Delegate_StatusChanged(ByVal sender As Object, ByVal e As JobCallbackEventArg)  
    89.         Try  
    90.             If e Is Nothing Or e.Job Is Nothing Then  
    91.                 Console.WriteLine("Server_Delegate_StatusChanged e Or e.Job is nothing.")  
    92.                 Exit Sub  
    93.             Else  
    94.                 Console.WriteLine("Server_Delegate_StatusChanged Begin!")  
    95.                 '  
    96.                 'Dim callBackOnce As ICallback   
    97.                 For Each callOnce As ICallback In clientCallBackChannles  
    98.                     CallBackOnce(callOnce, e)  
    99.                     'If e.ChangeReason = "Add" Then  
    100.                     '    Console.WriteLine("Server_Delegate_StatusChanged reason: Add")  
    101.                     '    callOnce.OnAdd(e.Job)  
    102.                     'Else  
    103.                     '    Console.WriteLine("Server_Delegate_StatusChanged reason: Modi")  
    104.                     '    callOnce.StatusChanged(e.Job)  
    105.                     'End If  
    106.                 Next  
    107.   
    108.                 Console.WriteLine("Server_Delegate_StatusChanged Done!")  
    109.             End If  
    110.         Catch ex As Exception  
    111.             Console.WriteLine("Server_OnStatusChange  Errors:" & ex.Message)  
    112.         End Try  
    113.     End Sub  
    114.   
    115.     '服务器端状态改变 ,则回调客户端 方法  
    116.     Private Sub Server_OnStatusChanged(ByVal sender As Object, ByVal e As JobCallbackEventArg)  
    117.         Try  
    118.             If e Is Nothing Or e.Job Is Nothing Then  
    119.                 Console.WriteLine("Server_OnStatusChange e Or e.Job is nothing.")  
    120.                 Exit Sub  
    121.             Else  
    122.                 Console.WriteLine("Server_OnStatusChange Begin!")  
    123.                 '回调  
    124.                 If e.ChangeReason = "Add" Then  
    125.                     Console.WriteLine("server_onStatusChanged reason: Add")  
    126.                     'callbackInterface.StatusChanged(e.Job)  
    127.                     callbackInterface.OnAdd(e.Job)  
    128.                 Else  
    129.                     Console.WriteLine("server_onStatusChanged reason: Modi")  
    130.                     callbackInterface.StatusChanged(e.Job)  
    131.                 End If  
    132.   
    133.                 Console.WriteLine("Server_OnStatusChange Done!")  
    134.             End If  
    135.         Catch ex As Exception  
    136.             Console.WriteLine("Server_OnStatusChange  Errors:" & ex.Message)  
    137.         End Try  
    138.     End Sub  
    139.   
    140.     '异步调用结束 处理  
    141.     Private Sub EndAsync(ByVal ar As IAsyncResult)  
    142.         '定义 处理 委托  
    143.         Dim dEndHandler As JobServerEventHandler = Nothing  
    144.   
    145.         Console.WriteLine("EndAsync Begin!")  
    146.         Try  
    147.             '取得 异步 参数 返回的 IAsyncResult,并转换为 远程 类型  
    148.             '定义远程异步处理参数, 对委托的异步操作结果  
    149.             Dim arRemote As System.Runtime.Remoting.Messaging.AsyncResult = CType(ar, System.Runtime.Remoting.Messaging.AsyncResult)  
    150.             '取得 返回 的异步 委托,并转换为 本地的事件委托  
    151.             dEndHandler = CType(arRemote.AsyncDelegate, JobServerEventHandler)  
    152.             '进行 异步 调用结束  处理  
    153.             dEndHandler.EndInvoke(ar)  
    154.             Console.WriteLine("EndAsync End!")  
    155.         Catch ex As Exception  
    156.             '发生错误 ,从事件委托 列表中 去除该 委托  
    157.             RemoveHandler onJobStatusChanged, dEndHandler  
    158.             'RemoveHandler onAdd, dEndHandler  
    159.   
    160.             Console.WriteLine("EndAsync Errors:" & ex.Message)  
    161.         End Try  
    162.     End Sub  
    163.   
    164.     '广播事件  
    165.     Private Sub BroadcastEvent(ByVal e As JobCallbackEventArg) ', ByVal tmpHandler As JobServerEventHandler)  
    166.         '判断是否有订阅事件  
    167.         'C#中 可以使用 null判断,但VB中不可以,但却可以直接 调用,不会出现异常  
    168.         '  
    169.         Console.WriteLine("BroadcastEvent Begin!")  
    170.         Try  
    171.             'For Each tmpH As JobServerEventHandler In onChangeEvents  '.GetInvocationList() 'onJobStatusChangedEvent.GetInvocationList()  
    172.             '    '异步调用  
    173.             '    tmpH.BeginInvoke(Me, e, New System.AsyncCallback(AddressOf EndAsync), Nothing)  
    174.             'Next  
    175.   
    176.             '保存了客户端通道列表后,不需要 委托列表直接在通道列表中进行回调即可  
    177.             Server_Delegate_StatusChanged(Me, e)  
    178.   
    179.             Console.WriteLine("BroadcastEvent End!")  
    180.         Catch ex As Exception  
    181.             Console.WriteLine("BroadcastEvent Errors:" & ex.Message)  
    182.         End Try  
    183.   
    184.     End Sub  
    185.   
    186.     Public Sub Accept() Implements IService.Accept  
    187.         Console.WriteLine("Accept Begin!")  
    188.         Console.WriteLine("启动服务实例")  
    189.         Try  
    190.             'callBack = OperationContext.Current.GetCallbackChannel<Core.ICallback>()  
    191.             '取得调用当前操作的客户端实例的通道  
    192.             callbackInterface = OperationContext.Current.GetCallbackChannel(Of ICallback)()  
    193.             '添加 服务器 端委托 链表  
    194.             'MyChangeHandler = New JobServerEventHandler(AddressOf Me.Server_OnStatusChanged)  
    195.             'AddHandler onJobStatusChanged, MyChangeHandler  
    196.             'AddHandler onJobStatusChanged, AddressOf Me.Server_OnStatusChanged  
    197.             'MyAddHandler = New JobServerEventHandler(AddressOf Me.Server_OnAdd)  
    198.             'AddHandler onAdd, MyAddHandler  
    199.   
    200.             '如果不用事件,直接使用委托  
    201.             AddDelegate(AddressOf Me.Server_Delegate_StatusChanged)  
    202.             '保存 回调通道列表  
    203.             AddCallBack(callbackInterface)  
    204.         Catch ex As Exception  
    205.             Console.WriteLine("Accept Errors: " & ex.Message)  
    206.         End Try  
    207.   
    208.         Console.WriteLine("Accept End!")  
    209.     End Sub  
    210.   
    211.     Private Sub AddCallBack(ByVal chl As ICallback)  
    212.         Console.WriteLine("AddCallBack Begin!")  
    213.         Try  
    214.             If jobs_Lock Is Nothing Then  
    215.                 jobs_Lock = New Object()  
    216.             End If  
    217.             If clientCallBackChannles Is Nothing Then  
    218.                 SyncLock jobs_Lock  
    219.                     clientCallBackChannles = New List(Of ICallback)  
    220.                 End SyncLock  
    221.             End If  
    222.   
    223.             SyncLock jobs_Lock  
    224.                 clientCallBackChannles.Add(chl)  
    225.                 Console.WriteLine("AddCallBack Done!")  
    226.             End SyncLock  
    227.   
    228.         Catch ex As Exception  
    229.             Console.WriteLine("AddCallBack Got Error:" & ex.Message)  
    230.         End Try  
    231.   
    232.   
    233.     End Sub  
    234.   
    235.     Private Sub AddDelegate(ByVal theDelegate As JobServerEventHandler)  
    236.         Console.WriteLine("AddDelegate Begin!")  
    237.         Try  
    238.             If jobs_Lock Is Nothing Then  
    239.                 jobs_Lock = New Object()  
    240.             End If  
    241.             If onChangeEvents Is Nothing Then  
    242.                 SyncLock jobs_Lock  
    243.                     onChangeEvents = New List(Of JobServerEventHandler)  
    244.                 End SyncLock  
    245.             End If  
    246.   
    247.             SyncLock jobs_Lock  
    248.                 onChangeEvents.Add(theDelegate)  
    249.                 Console.WriteLine("AddDelegate Done!")  
    250.             End SyncLock  
    251.         Catch ex As Exception  
    252.             Console.WriteLine("AddDelegate Got Error:" & ex.Message)  
    253.         End Try  
    254.   
    255.     End Sub  
    256.   
    257.     Public Sub AddJob(ByVal newJob As job) Implements IService.AddJob  
    258.         Console.WriteLine("AddJob")  
    259.         Try  
    260.             If jobs_Lock Is Nothing Then  
    261.                 jobs_Lock = New Object()  
    262.             End If  
    263.             If m_jobs Is Nothing Then  
    264.                 SyncLock jobs_Lock  
    265.                     m_jobs = New List(Of job)  
    266.                 End SyncLock  
    267.             End If  
    268.             For Each jobItem As job In m_jobs  
    269.                 If newJob.Name = jobItem.Name Then  
    270.                     Console.WriteLine("Job 已存在。")  
    271.                     Return  
    272.                 End If  
    273.             Next  
    274.   
    275.             '添加  
    276.             newJob.Status = "Sleeping"  
    277.             newJob.LastRunResult = "Created"  
    278.   
    279.             SyncLock jobs_Lock  
    280.                 m_jobs.Add(newJob)  
    281.             End SyncLock  
    282.   
    283.             Console.WriteLine("AddJob 添加完毕。开始广播事件...")  
    284.             '引发事件  
    285.             Dim e As JobCallbackEventArg = New JobCallbackEventArg()  
    286.             e.Job = newJob  
    287.             e.ChangeReason = "Add"  
    288.             '广播事件  
    289.             BroadcastEvent(e)  
    290.             'BroadcastEvent(e, onAdd)  
    291.             'RaiseEvent onAdd(Me, e)  
    292.             'RaiseEvent onJobStatusChanged(Me, e)  
    293.             Console.WriteLine("AddJob 广播事件完毕。")  
    294.         Catch ex As Exception  
    295.             Console.WriteLine("AddJob Errors: " & ex.Message)  
    296.         End Try  
    297.   
    298.         Console.WriteLine("AddJob End!")  
    299.     End Sub  
    300.   
    301.     '内部方法,用来取得 指定名称的 job  
    302.     Private Function GetJobByname(ByVal theJobName As String) As job  
    303.         For Each jobItem As job In m_jobs  
    304.             If jobItem.Name = theJobName Then  
    305.                 Return jobItem  
    306.             End If  
    307.         Next  
    308.   
    309.         Return Nothing  
    310.     End Function  
    311.   
    312.     Public Sub DoJob(ByVal jobName As String) Implements IService.DoJob  
    313.         Dim theJob As job = GetJobByname(jobName)  
    314.         Try  
    315.             Dim e As JobCallbackEventArg = New JobCallbackEventArg()  
    316.   
    317.             If theJob.Status = "Finished" Then  
    318.                 Return  
    319.             End If  
    320.   
    321.             theJob.Status = "Running"  
    322.             theJob.LastRunResult = "Working"  
    323.             theJob.LastRunTime = DateTime.Now  
    324.             e.Job = theJob  
    325.   
    326.             '广播事件  
    327.             BroadcastEvent(e)  
    328.             '  
    329.             Console.WriteLine("任务" + theJob.Name + "正在执行")  
    330.             '耗时  
    331.             System.Threading.Thread.Sleep(1000 * 10)  
    332.   
    333.             e = New JobCallbackEventArg()  
    334.             theJob.Status = "Finished"  
    335.             theJob.LastRunTime = DateTime.Now  
    336.             theJob.LastRunResult = "Done!"  
    337.             e.Job = theJob  
    338.             '广播事件  
    339.             BroadcastEvent(e)  
    340.   
    341.         Catch ex As Exception  
    342.             '将 job状态修改 为  
    343.             theJob.Status = "Sleeping"  
    344.             theJob.LastRunResult = "Fail"  
    345.         End Try  
    346.     End Sub  
    347.   
    348.     Public Function GetJobs() As System.Collections.Generic.List(Of job) Implements IService.GetJobs  
    349.         'System.Threading.Thread.Sleep(1000 * 5) '为何要如此设置?耗时吗?还是为了 错开 同步 问题  
    350.         Console.WriteLine("GetJobs")  
    351.   
    352.         Return m_jobs  
    353.     End Function  
    354. End Class  
    355.   
    356. '回调用 参数 类别  
    357. Public Class JobCallbackEventArg  
    358.     Inherits EventArgs  
    359.   
    360.     Private m_CallbackJob As job  
    361.   
    362.     Private m_ChangeReason As String  
    363.   
    364.     Public Property Job As job  
    365.         Get  
    366.             Return m_CallbackJob  
    367.         End Get  
    368.         Set(ByVal value As job)  
    369.             m_CallbackJob = value  
    370.         End Set  
    371.     End Property  
    372.   
    373.     Public Property ChangeReason As String  
    374.         Get  
    375.             Return m_ChangeReason  
    376.         End Get  
    377.         Set(ByVal value As String)  
    378.             m_ChangeReason = value  
    379.         End Set  
    380.     End Property  
    381. End Class  
    5)承载服务代码
    1. Imports System.Runtime.Serialization  
    2. Imports System.ServiceModel  
    3. Module Module1  
    4.   
    5.     Sub Main()  
    6.         Using host As ServiceHost = New ServiceHost(GetType(WcfJobService.JobServerImplement))  
    7.             host.Open()  
    8.   
    9.             Console.WriteLine("Service Started!")  
    10.   
    11.   
    12.             Console.WriteLine("Press any key to Exit!")  
    13.             Console.ReadKey()  
    14.   
    15.             host.Close()  
    16.         End Using  
    17.     End Sub  
    18.   
    19. End Module  
    承载服务配置 app.config 上文提到 的文章的例子中并没有关于Mex终结点,之所以在这里配置无数据终结点,是为了让客户端获取代理方便些。而且,在这里用的绑定是TCP,也就是说,这是个天然支持回调的协议。而且速度也很快,只是IIS6无法承载
    1. <?xml version="1.0" encoding="utf-8" ?>  
    2. <configuration>  
    3.     <system.diagnostics>  
    4.         <sources>  
    5.             <!-- 本节定义 My.Application.Log 的登录配置-->  
    6.             <source name="DefaultSource" switchName="DefaultSwitch">  
    7.                 <listeners>  
    8.                     <add name="FileLog"/>  
    9.                     <!-- 取消注释以下一节可写入应用程序事件日志-->  
    10.                     <!--<add name="EventLog"/>-->  
    11.                 </listeners>  
    12.             </source>  
    13.         </sources>  
    14.         <switches>  
    15.             <add name="DefaultSwitch" value="Information" />  
    16.         </switches>  
    17.         <sharedListeners>  
    18.             <add name="FileLog"  
    19.                  type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"  
    20.                  initializeData="FileLogWriter"/>  
    21.             <!-- 取消注释以下一节并用应用程序名替换 APPLICATION_NAME 可写入应用程序事件日志-->  
    22.             <!--<add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="APPLICATION_NAME"/> -->  
    23.         </sharedListeners>  
    24.     </system.diagnostics>  
    25.     <system.serviceModel>  
    26.         <services>  
    27.             <service name="WcfJobService.JobServerImplement" behaviorConfiguration ="MEX">  
    28.               <host>  
    29.                 <baseAddresses>  
    30.                   <!--<add baseAddress ="net.tcp://localhost:8322/"/>-->  
    31.                   <add baseAddress ="http://localhost:8300/"/>  
    32.                 </baseAddresses>  
    33.               </host>  
    34.                 
    35.               <!--<endpoint address="Event" binding="netTcpBinding"  
    36.                     bindingConfiguration="DuplexBinding" contract="WcfJobService.IService" />-->  
    37.               <endpoint address="Event" binding="wsDualHttpBinding"  
    38.                     bindingConfiguration="DuplexWsHttpBinding" contract="WcfJobService.IService" />  
    39.               <!--<endpoint address ="MEX" binding ="mexTcpBinding" contract ="IMetadataExchange" />-->  
    40.               <endpoint address ="http://localhost:8080/MEX" binding ="mexHttpBinding" contract ="IMetadataExchange" />  
    41.             </service>  
    42.         </services>  
    43.       <bindings>  
    44.         <wsDualHttpBinding>  
    45.           <binding name="DuplexWsHttpBinding" sendTimeout ="00:00:05"></binding>  
    46.         </wsDualHttpBinding>  
    47.         <netTcpBinding>  
    48.           <binding name ="DuplexBinding" sendTimeout ="00:00:03" ></binding>  
    49.         </netTcpBinding>  
    50.         <wsHttpBinding>  
    51.           <binding name ="wsHttpBindingCallBack" sendTimeout ="00:00:05"></binding>  
    52.         </wsHttpBinding>  
    53.       </bindings>  
    54.       <behaviors >  
    55.         <serviceBehaviors >  
    56.           <behavior name="MEX">  
    57.             <serviceMetadata />  
    58.           </behavior>  
    59.         </serviceBehaviors>  
    60.       </behaviors>  
    61.     </system.serviceModel>  
    62. </configuration>  
    QQ日志其实真的挺笨的。这和腾迅出的所有产品一样,笨得要死。只是我没有用其他的博客之类的,也犯不着为了一篇文章去申请了。呵呵。其实,细想起来,我们每天离不开的很多东西其实都是粗制品,比如WINDOWS,比如QQ,真的是不用不行,用着着实不爽。呵呵。是不是和我们人生一样,不完美的才是真实的。MSN也好,ICQ也好,其实都比QQ好用得多,但是都死掉了。就拿QQ那个视频来说,真是慢得要死,4M的宽带看高清都不卡,它偏偏要卡,画面只有那么小,真不知腾迅的技术人员是怎么想的。还有那个远程,真是最没用的东西!比起TeamStream差得天上去了。不说了。QQ日志一写多了就犯病。只好把下面的内容再多分几篇了。

     

    6)客户端

    配置文件app.config

    1. <?xml version="1.0" encoding="utf-8" ?>  
    2. <configuration>  
    3.     <startup>  
    4.         <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client" />  
    5.     </startup>  
    6.     <system.serviceModel>  
    7.         <bindings>  
    8.             <netTcpBinding>  
    9.                 <binding name="NetTcpBinding_IService" closeTimeout="00:01:00"  
    10.                     openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"  
    11.                     transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"  
    12.                     hostNameComparisonMode="StrongWildcard" listenBacklog="10"  
    13.                     maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"  
    14.                     maxReceivedMessageSize="65536">  
    15.                     <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"  
    16.                         maxBytesPerRead="4096" maxNameTableCharCount="16384" />  
    17.                     <reliableSession ordered="true" inactivityTimeout="00:10:00"  
    18.                         enabled="false" />  
    19.                     <security mode="Transport">  
    20.                         <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />  
    21.                         <message clientCredentialType="Windows" />  
    22.                     </security>  
    23.                 </binding>  
    24.             </netTcpBinding>  
    25.           <wsDualHttpBinding>  
    26.             <binding name="wsDualHttpBinding_IService"  closeTimeout="00:01:00"  
    27.                     openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"  
    28.                     transactionFlow="false" hostNameComparisonMode="StrongWildcard"   
    29.                     maxBufferPoolSize="524288" maxReceivedMessageSize="65536">  
    30.                     <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"  
    31.                         maxBytesPerRead="4096" maxNameTableCharCount="16384" />                
    32.             </binding>  
    33.           </wsDualHttpBinding>  
    34.         </bindings>  
    35.         <client>  
    36.             <!--<endpoint address="net.tcp://localhost:8322/Event" binding="netTcpBinding"  
    37.                 bindingConfiguration="NetTcpBinding_IService" contract="JobServiceClient.IService"  
    38.                 name="NetTcpBinding_IService">-->  
    39.           <endpoint address="http://localhost:8300/Event" binding="wsDualHttpBinding"  
    40.                 bindingConfiguration="wsDualHttpBinding_IService" contract="JobServiceClient.IService"  
    41.                 name="wsDualHttpBinding_IService">  
    42.                 <!--<identity>  
    43.                     <userPrincipalName value="COMPUTER\Administrator" />  
    44.                 </identity>-->  
    45.             </endpoint>  
    46.         </client>  
    47.     </system.serviceModel>  
    48. </configuration>  

    客户端代码(Form)  说明:由于使用了Form作为客户端,就涉及到一个工作线程的问题,因为多线程中使用工作线程是最简单的,也是最便捷的。

     

    1. Imports System.Runtime.Serialization  
    2. Imports System.ServiceModel  
    3.   
    4. Public Class Form1  
    5.     Implements JobServiceClient.IServiceCallback  
    6.   
    7.     Private client As JobServiceClient.ServiceClient  
    8.     Private jobList As List(Of JobServiceClient.job) = New List(Of JobServiceClient.job)  
    9.   
    10.     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click  
    11.         Dim jobName As String = InputBox("输入新 JOB 名称!")  
    12.         If jobName = "" Then  
    13.             MessageBox.Show("JOB 名称必须输入!")  
    14.             Exit Sub  
    15.         End If  
    16.   
    17.         Dim newJob As JobServiceClient.job = New JobServiceClient.job()  
    18.         newJob.Name = jobName  
    19.         newJob.LastRunResult = "Sleeping"  
    20.         newJob.LastRunTime = DateTime.Now  
    21.         newJob.Status = "Sleeping"  
    22.   
    23.         client.AddJob(newJob)  
    24.   
    25.     End Sub  
    26.   
    27.     Public Sub OnAdd(ByVal newJob As JobServiceClient.job) Implements JobServiceClient.IServiceCallback.OnAdd  
    28.         Dim tmpitem As ListViewItem = CreateViewListItem(newJob)  
    29.         Me.ListView1.Items.Add(tmpitem)  
    30.     End Sub  
    31.   
    32.     Public Sub StatusChanged(ByVal job As JobServiceClient.job) Implements JobServiceClient.IServiceCallback.StatusChanged  
    33.         '遍历 列表 项  
    34.         For Each tmpItem As ListViewItem In Me.ListView1.Items  
    35.             If tmpItem.Text = job.Name Then  
    36.                 '修改 JOB 状态  
    37.                 tmpItem.SubItems(1).Text = job.Status  
    38.                 tmpItem.SubItems(2).Text = job.LastRunTime.ToString()  
    39.                 tmpItem.SubItems(3).Text = job.LastRunResult  
    40.                 '判断 JOB状态  
    41.                 If job.LastRunResult = "Fail" Then  
    42.                     tmpItem.ImageIndex = 2  
    43.                 ElseIf job.Status = "Running" Then ' job.LastRunResult = "Done" Then  
    44.                     tmpItem.ImageIndex = 0  
    45.                 ElseIf job.Status = "Sleeping" Then  
    46.                     tmpItem.ImageIndex = 1  
    47.                 Else  
    48.                     tmpItem.ImageIndex = 1 'other  
    49.                 End If  
    50.             End If  
    51.         Next  
    52.     End Sub  
    53.   
    54.     Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load  
    55.         '初始化 远程  
    56.         Try  
    57.             '取得自身 上下文实例  
    58.             Dim instanceMe As InstanceContext = New InstanceContext(Me)  
    59.             client = New JobServiceClient.ServiceClient(instanceMe)  
    60.             '订阅事务  
    61.             client.Accept()  
    62.             '加载Job列表  
    63.             LoadJobs()  
    64.         Catch ex As Exception  
    65.             MessageBox.Show(ex.Message)  
    66.         End Try  
    67.     End Sub  
    68.   
    69.     Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork  
    70.         '后台进程 工作  
    71.         '取得 JOB 列表  
    72.         Try  
    73.             jobList = client.GetJobs()  
    74.             If jobList Is Nothing Then  
    75.                 Exit Sub  
    76.             End If  
    77.   
    78.             '判断 当前线程工作状态  
    79.             If Me.ListView1.InvokeRequired Then  
    80.                 '异步  
    81.                 ListView1.Invoke(New MethodInvoker(AddressOf Me.UpdateViewList))  
    82.   
    83.             Else  
    84.                 Me.UpdateViewList()  
    85.             End If  
    86.         Catch ex As Exception  
    87.             MessageBox.Show(ex.Message)  
    88.         End Try  
    89.   
    90.   
    91.     End Sub  
    92.   
    93.     Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted  
    94.         '后台进程 工作完成  
    95.         Me.TextBox1.Text = "获取列表完毕!"  
    96.     End Sub  
    97.   
    98.     Private Sub LoadJobs()  
    99.         '载入列表  
    100.         '启动后台线程  
    101.         Me.TextBox1.Text = "正在获取JOB列表"  
    102.         Me.BackgroundWorker1.RunWorkerAsync()  
    103.   
    104.     End Sub  
    105.   
    106.     Private Sub UpdateViewList()  
    107.         '重新载入列表  
    108.         Me.ListView1.Items.Clear()  
    109.         If jobList.Count < 1 Then  
    110.             Me.TextBox1.Text = "JOB列表为空。请先添加JOB。"  
    111.             Exit Sub  
    112.         End If  
    113.         For Each tmpJob As JobServiceClient.job In jobList  
    114.             Dim tmpItem As ListViewItem = CreateViewListItem(tmpJob)  
    115.             Me.ListView1.Items.Add(tmpItem)  
    116.         Next  
    117.     End Sub  
    118.   
    119.     Private Function CreateViewListItem(ByVal theJob As JobServiceClient.job) As ListViewItem  
    120.         '通过 job 创建一个新的 列表项  
    121.         Dim itemStr() As String = {theJob.Name, theJob.Status, theJob.LastRunTime.ToString(), theJob.LastRunResult}  
    122.   
    123.         Dim item As ListViewItem = New ListViewItem(itemStr)  
    124.   
    125.         If theJob.LastRunResult = "Fail" Then '"Sleeping" Then  
    126.             item.ImageIndex = 2 'Sleeping  
    127.         ElseIf theJob.Status = "Running" Then  
    128.             item.ImageIndex = 0 'Done  
    129.             'ElseIf theJob.Status = "Sleeping" Then  
    130.             '    item.ImageIndex = 3 'Delete  
    131.         Else  
    132.             item.ImageIndex = 1 'Fail  
    133.         End If  
    134.   
    135.         item.Tag = theJob  
    136.   
    137.         Return item  
    138.   
    139.     End Function  
    140.   
    141.     Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click  
    142.         'LoadJobs()  
    143.         'Do Job  
    144.         '取得列表中被选择的行  
    145.         'If Me.ListView1.SelectedIndices   
    146.         For Each iIndex As Integer In Me.ListView1.SelectedIndices  
    147.             client.DoJob(Me.ListView1.Items(iIndex).Text)  
    148.             'MessageBox.Show(Me.ListView1.Items(iIndex).Text)  
    149.         Next  
    150.     End Sub  
    151.   
    152.     Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click  
    153.         'delete job  
    154.     End Sub  
    155.   
    156.     Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click  
    157.         'Exit  
    158.         End  
    159.     End Sub  
    160. End Class  

    QQ不让传附件,要钱的,马化腾不当官真是可惜。全部代码可到以下地址下载:http://pan.baidu.com/s/1eSdxGoq 密码: 8qky

    四、总结 要想在服务器端进行事件广播,其实最关键的是,将事件列表保存起来,然后在事件发生时,遍历就好了。然后去通知每一个客户端。在网上的文章 中之所以要用到会话,而且要保持会话状态 就是因只有这样才能在事件异步调用过程中找到自身的客户端回调通道。 而经过验证得之,实际上,只要我们把客户端的回调通道保存在一个共享数组中,这样,我们只要在发生事件时遍历这个数组就可以通知到每个订阅者。所以,我们只需要项目中服务和客户端可以进行回调就可以,这样我们可以使用wsDualHttpBinding进行设计 。而且也可以不用委托或者事件来进行。我们只要把事件状态回调就可以了。而这个回调本身是单向的。也不用异步处理。只要处理好服务器端的并发就可以了。 所以就有了下面的结构:
    服务器端进行远程订阅:将订阅的事件和客户端回调通道保存到列表中。 服务器端发生要通知的事件:遍历两个数组进行回调通知。
    当然,这个还不很完善,比如,在客户端关闭后,服务器端在回调时会发生异常。如果有大量的客户端关闭或网络异常,会导致服务器端阻滞,当然可以使用多线程 来解决这个问题。
    下面是不用事件的服务契约和服务实现(部分代码,完整代码见:http://pan.baidu.com/s/1eSdxGoq 密码: 8qky,这里的代码就是没有使用委托,也没有使用事件进行的广播。) 

    (1)服务端启动后

    (2)客户端启动后,服务端得到消息

    (3)客户端启动后

    (4)客户端加入一个任务

    (5)服务端得到客户端加入任务通知

    (6)客户端执行任务及服务端得到任务执行情况

     

    代码和附件说明:所见的都是最后版本,也就是没有用会话,没有用事件,也没有用委托来实现事件广播的。

     

    注:代码部分因为是360网盘,不知为何已不能使用了。有空传一份到这里。

    转载于:https://www.cnblogs.com/mqmelon/p/4757507.html

    展开全文
  • 再来说一下,没有专业技能的人应该...自媒体现在是比较热门的一个领域,比如说,你擅长织毛衣、织围巾之类的手工活,那么你你的作品发布到网上。还可以做直播推广,这就是现在非常热门的直播带货了。通过人群来...
  • 8.DOClever开源免费,支持内网部署,很多公司考虑数据的安全性,不愿意接口放公网上,没有关系,DOClever给出一个方便快捷的解决方案,你可以平台放自己的内网上,完全不需要连接外网,同时功能一样也不少...
  • 基本能撸过能看到的代码都过了一遍,此文篇幅较长,建议保存(star)再看。传送门: <a href="https://github.com/Nealyang/PersonalBlog/issues/11">Nealyang personal blog</a></strong> 前言 ...
  • 2021-01-17

    2021-01-17 23:54:33
    自从在大学学了HTML和JS之后,一直都在想,怎么将自己写的HTML网页发布到网上像百度一样让任意用户可以访问呢?于是我便做了一些尝试,并有了如下收获: 首先,网站上传到网站让别人访问需要以下东西: 1:域名 2...
  • 我们先去网上找了一些关于二手调查的问题,然后对于问题做了分析,我们应该了解什么东西怎么了解,在最后经过讨论有些题目进行融合提炼,尽量问题的个数控制子15个以内,就这样我们的问卷诞...
  • 所有分享的东西都可看做新鲜事,现在要求从这三张表将相同的几个字段的数据全部查找出来按照发布时间先后排序(至于为什么不这三张表的数据整一张表里面这是由于数据库是这样设计的,咱这先不讨论数据库设计的...
  • 我是弄服务器的……程序开发人员网站做好了,他说用什么调用TOMCAT功能发布是可以正常用的(实例URL:http://petstarclub.512kc.com:8888/) 但是我按照网上的一些教程配好了apache+tomcat+php+mysql的环境后,这...
  •  负责显示指定的商品详细信息,包括图片、名字、价格、数量等,当一个商品被点击之后,通过返回的id查询这个数据集合,跳转商品详细信息的页面,商品发布者可以在下方查看留言,并且与有意者打成交易意向。...
  • 工具链就是很多工具打包在一起发布的方便你开发的东西。具体安装方*看我另一篇笔记。 另外如果你开发LINUX就要用ARM-LINUX-TOOLS,不一样,不通用。 5 U-BOOT 大名鼎鼎的BOOTLOADER生成工具,同类的好象还有VIVI...
  • 《你必须知道的495个C语言问题》

    热门讨论 2010-03-20 16:41:18
    5.15 有没有什么简单点儿的办法理解所有这些与空指针有关的东西呢? 60 5.16 考虑有关空指针的所有这些困惑,要求它们的内部表示都必须为0不是更简单吗? 60 5.17 说真的,真有机器用非零空指针吗,或者不同...
  • 糕粉咱们在网上也能买 64 00:02:35,880 --> 00:02:38,080 月饼馅里边所有的食材 65 00:02:38,080 --> 00:02:40,120 都在网上都可以买 66 00:02:40,120 --> 00:02:43,080 给它和的粘稠能粘一块 67...
  • o 6.13 考虑有关空指针的所有这些困惑, 难道要求它们内部表达都必须为 0 不是更简单吗? o 6.14 说真的, 真有机器用非零空指针吗, 或者不同类型用不同的表达? o 6.15 运行时的 ``空指针赋值" 错误是什么意思...
  • 5.15 有没有什么简单点儿的办法理解所有这些与空指针有关的东西呢? 5.16 考虑有关空指针的所有这些困惑,要求它们的内部表示都必须为0不是更简单吗? 5.17 说真的,真有机器用非零空指针吗,或者不同类型用...
  • 还是先看一下【十天学会ASP教程】,大家所需要了解的不是ASP的程序怎么写,而是怎么构建服务器,怎么使用HTML表单,同时对SQL语句有一个基础和理解,因为在本文里我不会将将一些基础的东西。 废话不多说,开始我们...
  • 5.15 有没有什么简单点儿的办法理解所有这些与空指针有关的东西呢? 60 5.16 考虑有关空指针的所有这些困惑,要求它们的内部表示都必须为0不是更简单吗? 60 5.17 说真的,真有机器用非零空指针吗,或者不同...
  • 要么在网上订 要不就是托在海边的朋友 0:06:22.376,0:06:23.282 好吃真的好吃 0:06:23.318,0:06:24.078 寄过来 0:06:25.551,0:06:29.799 好啦 大家可以不是海边的朋友可以尝试一下 0:06:30.161,0:06:32.503 下次...
  • 你必须知道的495个C语言问题(PDF)

    热门讨论 2009-09-15 10:25:47
    3.12 我需要根据条件一个复杂的表达式赋值给两个变量中的一 个。可以用下边这样的代码吗? ((condition) ? a : b) = complicated expression; . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 目录iii ...
  • 如果程序改为这样: #include #include "widget.h" #include "mydlg.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); myDlg my1; Widget w; if(my1.exec()==QDialog::Accepted) { w.show(); ...
  • 如果你是一个翻译爱好者,来试试这个软件,一定会让你爱不释手,在下一版中将增加的随时随地注解功能,你可以在任何地方,增加注解,来解释你对某一句或是某一个单词的看法,你可以自己译过的文章在网上发布,共享给网友,...
  • Apache Pig: 是一个基于Hadoop的大规模数据分析工具,它提供的SQL-LIKE语言叫Pig Latin,该语言的编译器会类SQL的数据分析请求转换为一系列经过优化处理的MapReduce运算 【不准备学,计划Hive代替Pig】 ...
  • 北邮的专业课真题会在每年的8、9月份在北京邮电大学研究生信息招生网上公开供考生下载。届时,同学们可以在网站上下载真题,需要特别注意的是,北邮官方并不会公布真题答案。 1. 801真题 2016年801通信原理真题 ...
  • 同步发布在博客</a></p> <p><a href="https://github.com/shengxinjing/my_blog/tree/master/log_visual">项目地址,跪求右上角star :star: :star2: :stars: 基于python,前端基于echarts,力求用简单的...

空空如也

空空如也

1 2
收藏数 30
精华内容 12
热门标签
关键字:

怎么把东西发布到网上