SuperSocket入门(二)- 探索AppServer、AppSession,Conmmand和App.config
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SuperSocket.Common;
using SuperSocket.SocketBase;
using SuperSocket.SocketBase.Protocol; /****************************************************************
* 作者:黄昏前黎明后
* CLR版本:4.0.30319.42000
* 创建时间:2017-01-19 00:02:17
* 2017
* 描述说明:自定义连接类MySession,继承AppSession,并传入到AppSession
*
* 修改历史:
*
*
*****************************************************************/
namespace SuperSocketDemo.Session
{ /// <summary>
/// 自定义连接类MySession,继承AppSession,并传入到AppSession
/// </summary>
public class MySession : AppSession<MySession>
{
/// <summary>
/// 新连接
/// </summary>
protected override void OnSessionStarted()
{
//输出客户端IP地址
Console.WriteLine(this.LocalEndPoint.Address.ToString());
this.Send("Hello User,Welcome to SuperSocket Telnet Server!");
} /// <summary>
/// 未知的Command
/// </summary>
/// <param name="requestInfo"></param>
protected override void HandleUnknownRequest(StringRequestInfo requestInfo)
{
this.Send("unknow");
} /// <summary>
/// 捕捉异常并输出
/// </summary>
/// <param name="e"></param>
protected override void HandleException(Exception e)
{
this.Send("error: {0}", e.Message);
} /// <summary>
/// 连接关闭
/// </summary>
/// <param name="reason"></param>
protected override void OnSessionClosed(CloseReason reason)
{
base.OnSessionClosed(reason);
}
}
}
MySession类
using SuperSocket.SocketBase;
using SuperSocket.SocketBase.Config;
using SuperSocketDemo.Session;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; /****************************************************************
* 作者:黄昏前黎明后
* CLR版本:4.0.30319.42000
* 创建时间:2017-01-19 00:15:45
* 2017
* 描述说明:自定义服务器类MyServer,继承AppServer,并传入自定义连接类MySession
*
* 修改历史:
*
*
*****************************************************************/
namespace SuperSocketDemo.Server
{
/// <summary>
/// 自定义服务器类MyServer,继承AppServer,并传入自定义连接类MySession
/// </summary>
public class MyServer : AppServer<MySession>
{
protected override void OnStartup()
{
base.OnStartup();
// Console.WriteLine("服务器启动");
} /// <summary>
/// 输出新连接信息
/// </summary>
/// <param name="session"></param>
protected override void OnNewSessionConnected(MySession session)
{
base.OnNewSessionConnected(session);
//输出客户端IP地址
Console.Write("\r\n" + session.LocalEndPoint.Address.ToString() + ":连接");
} /// <summary>
/// 输出断开连接信息
/// </summary>
/// <param name="session"></param>
/// <param name="reason"></param>
protected override void OnSessionClosed(MySession session, CloseReason reason)
{
base.OnSessionClosed(session, reason);
Console.Write("\r\n" + session.LocalEndPoint.Address.ToString() + ":断开连接");
} protected override void OnStopped()
{
base.OnStopped();
Console.WriteLine("服务已停止");
}
}
}
MyServer类
public class Hello: CommandBase<MySession, StringRequestInfo>
{
/// <summary>
/// 自定义执行命令方法,注意传入的变量session类型为MySession
/// </summary>
/// <param name="session">会话</param>
/// <param name="requestInfo">请求数据信息</param>
public override void ExecuteCommand(MySession session, StringRequestInfo requestInfo)
{
session.Send(string.Format("Hello {0}:{1} {2}", session.Config.Ip, session.Config.Port, requestInfo.Body));
}
}
Hello类
定义一个名为"ADD"的类去处理Key为"ADD"的请求:
public class ADD : CommandBase<MySession, StringRequestInfo>
{
public override void ExecuteCommand(MySession session, StringRequestInfo requestInfo)
{
session.Send(requestInfo.Parameters.Select(p => Convert.ToInt32(p)).Sum().ToString());
}
}
Add类
定义一个名为"MULT"的类去处理Key为"MULT"的请求:
public class MULT : CommandBase<MySession, StringRequestInfo>
{
public override void ExecuteCommand(MySession session, StringRequestInfo requestInfo)
{
var result = ; foreach (var factor in requestInfo.Parameters.Select(p => Convert.ToInt32(p)))
{
result *= factor;
} session.Send(result.ToString());
}
}
Mult类
定义一个名为"Echo"的类去处理Key为"Echo"的请求:
public class Echo: CommandBase<MySession, StringRequestInfo>
{
public override void ExecuteCommand(MySession session, StringRequestInfo requestInfo)
{
session.Send(requestInfo.Body);
}
}
Echo类
同时我们要移除请求处理方法的注册,因为它和命令不能同时被支持,注释下面代码即可
//appServer.NewRequestReceived += new RequestHandler<MySession, StringRequestInfo>(appServer_NewRequestReceived);
4、配置App.config使用BootStrap启动SuperSocket
SuperSocket配置section SuperSocket使用.NET自带的配置技术,SuperSocket有一个专门的配置Section.使用配置启动SuperSocket可以灵活配置选项
配置完成后,还需要修改program类。将原有在program中定义的端口信息以及方法注释,只保留服务启动和停止的代码。引入using SuperSocket.SocketEngine;使用BootStrap启动
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SuperSocket.SocketBase;
using SuperSocket.SocketBase.Protocol;
using SuperSocket.SocketEngine;
using SuperSocketDemo.Server; /****************************************************************
* 作者:黄昏前黎明后
* CLR版本:4.0.30319.42000
* 创建时间:2017-01-19 00:02:17
* 2017
* 描述说明:服务启动和停止入口
*
* 修改历史: 2017 -01-19 调整自定义mysession和myserver
*
*
*****************************************************************/
namespace SuperSocketDemo
{
class Program
{
/// <summary>
/// SuperSocket服务启动或停止
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
Console.WriteLine("请按任何键进行启动SuperSocket服务!");
Console.ReadKey();
Console.WriteLine();
var bootstrap = BootstrapFactory.CreateBootstrap(); if (!bootstrap.Initialize())
{
Console.WriteLine("初始化失败!");
Console.ReadKey();
return;
} //修改appserver为myserver
//var appServer = new AppServer();
// var appServer = new MyServer();
//注册事件
// appServer.NewSessionConnected += new SessionHandler<AppSession>(appServer_NewSessionConnected);
//appServer.NewRequestReceived += new RequestHandler<AppSession, StringRequestInfo>(appServer_NewRequestReceived); //设置端口号
//int port = 2017;
//启动应用服务端口
//if (!appServer.Setup(port)) //启动时监听端口2017
//{
// Console.WriteLine("服务端口启动失败!");
// Console.ReadKey();
// return;
//} //Console.WriteLine(); ////尝试启动应用服务
//if (!appServer.Start())
//{
// Console.WriteLine("服务启动失败!");
// Console.ReadKey();
// return;
//}
var result = bootstrap.Start(); Console.WriteLine("服务正在启动: {0}!", result); if (result == StartResult.Failed)
{
Console.WriteLine("服务启动失败!");
Console.ReadKey();
return;
}
Console.WriteLine("服务启动成功,请按'E'停止服务!"); while (Console.ReadKey().KeyChar != 'E')
{
Console.WriteLine();
continue;
} //停止服务
// appServer.Stop();
bootstrap.Stop();
Console.WriteLine("服务已停止!");
Console.ReadKey();
}
/// <summary>
/// 在事件处理代码中发送欢迎信息给客户端
/// </summary>
/// <param name="session"></param>
//static void appServer_NewSessionConnected(AppSession session)
//{
// session.Send("Welcome to SuperSocket Telnet Server!");
//}
/// <summary>
///客户端请求处理
/// </summary>
/// <param name="session">会话</param>
/// <param name="requestInfo">请求信息</param> //static void appServer_NewRequestReceived(AppSession session, StringRequestInfo requestInfo)
//{
// switch (requestInfo.Key.ToUpper())
// {
// case ("ECHO"):
// session.Send(requestInfo.Body);
// break; // case ("ADD"):
// session.Send(requestInfo.Parameters.Select(p => Convert.ToInt32(p)).Sum().ToString());
// break; // case ("MULT"): // var result = 1; // foreach (var factor in requestInfo.Parameters.Select(p => Convert.ToInt32(p)))
// {
// result *= factor;
// } // session.Send(result.ToString());
// break;
// }
//}
}
}
program类
最后我们看一下修改后程序的运行结果:
断开调试工具看一下效果,可以看到服务端显示客户端断开连接
注意事项:

总结:
通过自定义Session和Server,可以实现我们自己的AppSession和AppServer允许你根据你业务的需求来方便的扩展SuperSocket,你可以绑定session的连接和断开事件,服务器实例的启动和停止事件。你还可以在AppServer的Setup方法中读取你的自定义配置信息。总而言之,这些功能让你方便的创建一个你所需要的socket服务器成为可能。
SuperSocket入门(二)- 探索AppServer、AppSession,Conmmand和App.config的更多相关文章
- java虚拟机入门(二)-探索内存世界
上节简单介绍了一下jvm的内存布局以及简单概念,那么对于虚拟机来说,它是怎么一步步的让我们能执行方法的呢: 1.首先,jvm启动时,跟个小领导一样会根据配置参数(没有配置的话jvm会有默认值)向大领导 ...
- SuperSocket入门(三)-Telnet多服务实例和服务实例交互配置详解
在SuperSocket入门(二)中我们已经简单了解了通过配置App.config文件使用BootStrap启动SuperSocket服务.我们先来看一下上个案例中的基本配置文件示例: < ...
- SuperSocket基础二
SuperSocket基础(二)-----一个完整的SocketServer项目 由于时间关系未能及时更新,关于SuperSocket,对于初学者而言,一个SuperSock的Server真的不好写. ...
- IM开发者的零基础通信技术入门(二):通信交换技术的百年发展史(下)
1.系列文章引言 1.1 适合谁来阅读? 本系列文章尽量使用最浅显易懂的文字.图片来组织内容,力求通信技术零基础的人群也能看懂.但个人建议,至少稍微了解过网络通信方面的知识后再看,会更有收获.如果您大 ...
- 脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?
1.引言 本文接上篇<脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手>,继续脑残式的网络编程知识学习 ^_^. 套接字socket是大多数程序员都非常熟悉的概念,它是计算机 ...
- [转帖]脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?
脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么? http://www.52im.net/thread-1732-1-1.html 1.引言 本文接上篇<脑残式网 ...
- 【原创】NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示
前言 NIO框架的流行,使得开发大并发.高性能的互联网服务端成为可能.这其中最流行的无非就是MINA和Netty了,MINA目前的主要版本是MINA2.而Netty的主要版本是Netty3和Netty ...
- Entity Framework 程序设计入门二 对数据进行CRUD操作和查询
前一篇文章介绍了应用LLBL Gen生成Entity Framework所需要的类型定义,用一行代码完成数据资料的读取, <LLBL Gen + Entity Framework 程序设计入门& ...
- Swift语法基础入门二(数组, 字典, 字符串)
Swift语法基础入门二(数组, 字典, 字符串) 数组(有序数据的集) *格式 : [] / Int / Array() let 不可变数组 var 可变数组 注意: 不需要改变集合的时候创建不可变 ...
随机推荐
- javascript 回调, 单线程执行
原文: http://www.cnblogs.com/aaronjs/p/3322466.html 这里的"回调"并不是"阻塞",而会空出执行线程,直至操作完成 ...
- @media max-width 与jquery宽度取值的差异
最近写了个响应式网站,有些效果通过用jq的$(window).width()来判断屏幕宽度,当屏幕宽度小于1366时一些参数发生变化.@media中也有小于1366的判断条件,但是用起来的时候发现一个 ...
- ios开发证书,描述文件,bundle ID的关系
苹果为了控制应用的开发与发布流程,制定了一套非常复杂的机制.这里面的关键词有:个人开发者账号,企业开发者账号,bundle ID,开发证书,发布证书(又叫"生产证书"),开发描述文 ...
- The 2014 ACMICPC Asia Regional Xian Online
[A]签到题 [B]后缀数组 [C]染色,DP(感觉可出) [D]BFS搜索,有点麻烦 [E]博弈论,Nim博弈 [F]BFS状态搜索 [G]概率DP+状态压缩 [H]异或+构造 [I]矩阵快速幂(队 ...
- bzoj3322 最大生成树+LCA
题目大意:给个无向图,每条边有个限制,每个点最多能买入和卖出一定黄金:然后按顺序走过n个点,求每个卖出黄金的点最多能卖出多少黄金 一开始有点懵,想着怎么再图上做这个问题,后来知道要先建一棵最大生成树 ...
- 加载window事件
$(document).ready()和window.onload的区别 发表于 2012-08-29 由 admin 以浏览器装载文档为例,在页面加载完毕后,浏览器会通过JavaScript为DOM ...
- OpenStack - liberty CentOS 7
OpenStack私有云部署 Controller Node: em1(10.6.17.11),em2() Computer Node: em1(10.6.17.12),e ...
- WKWebKit基础
UIWebView & UIWebViewDelegate 这个两个东西在 WKWebKit 中被重构成 14 个类 3 个协议. WKWebKit Framework Classes WKB ...
- 《玩转Bootstrap(基础)》笔记
基本的HTML模板 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- iOS开发——浅谈构架与用户体验
工作不是千篇一律的重复,从中寻找乐趣才是我们应该做的. 作为一名码农,做过几个项目,每次做项目的时候都会自己构思,如果完全是我自己设计,会怎么去设计?心里一直没有满意的答案,不管怎么布局,好像都感觉差 ...