ASP.NET Core Web API的启动类(Startup)
using com. uplus. common ;
using com. uplus. log4net ;
using Microsoft. AspNetCore. Authentication. Cookies ;
using Microsoft. AspNetCore. Authentication. JwtBearer ;
using Microsoft. AspNetCore. Builder ;
using Microsoft. AspNetCore. Hosting ;
using Microsoft. AspNetCore. Http ;
using Microsoft. AspNetCore. Http. Features ;
using Microsoft. AspNetCore. Mvc ;
using Microsoft. AspNetCore. StaticFiles ;
using Microsoft. Extensions. DependencyInjection ;
using Microsoft. Extensions. Hosting ;
using Microsoft. IdentityModel. Tokens ;
using Newtonsoft. Json ;
using Newtonsoft. Json. Serialization ;
using System ;
using System. Collections. Generic ;
using System. Diagnostics ;
using System. IO ;
using System. Management ;
using System. Net. WebSockets ;
using System. Text ;
using System. Threading ;
using System. Web ;
using WebApi. Bill. Biz ;
using WebApi. Common ;
using WebApi. Models ;
using IApplicationLifetime = Microsoft. AspNetCore. Hosting. IApplicationLifetime ;
namespace WebApi
{
public class Startup
{
public static Dictionary< string , WebSocket> dicWebSocket = new Dictionary< string , WebSocket> ( ) ;
public static Dictionary< string , DateTime> dicWebSocketTime = new Dictionary< string , DateTime> ( ) ;
private string webRootPath = "" ;
public static TcpServerHelper tcpServer = null ;
public void ConfigureServices ( IServiceCollection services)
{
Log4Helper. Initializer ( ) ;
services. AddHttpContextAccessor ( ) ;
services. AddScoped < LoginInfo> ( ) ;
services. AddScoped < HostingEnvironment> ( ) ;
services. AddRouting ( options => options. LowercaseUrls = true ) ;
services. AddCors ( options =>
{
options. AddPolicy ( "any" , builder =>
{
builder. AllowAnyHeader ( )
. AllowAnyOrigin ( ) ;
} ) ;
} ) ;
services. AddAuthentication ( options =>
{
options. DefaultScheme = CookieAuthenticationDefaults. AuthenticationScheme;
} ) . AddCookie ( options =>
{
options. Cookie. HttpOnly = true ;
} ) ;
services. AddDistributedMemoryCache ( ) . AddSession ( o =>
{
o. IdleTimeout = TimeSpan. FromDays ( 60 ) ;
} ) . AddMvc ( opt =>
{
opt. UseCentralRoutePrefix ( new RouteAttribute ( "api/[controller]/[action]" ) ) ;
} ) ;
services. AddMvc ( option =>
{
option. EnableEndpointRouting = false ;
} ) . SetCompatibilityVersion ( CompatibilityVersion. Version_3_0) . AddControllersAsServices ( ) . AddNewtonsoftJson
(
json =>
{
json. SerializerSettings. ContractResolver = new DefaultContractResolver ( ) ;
json. SerializerSettings. DateFormatString = "yyyy-MM-dd HH:mm:ss" ;
json. SerializerSettings. ReferenceLoopHandling = ReferenceLoopHandling. Ignore;
}
) ;
services
. AddAuthentication ( JwtBearerDefaults. AuthenticationScheme)
. AddJwtBearer ( options =>
{
options. TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = AppConfigurtaion. GetSecondSection ( "JwtSetting" , "Issuer" ) ,
ValidAudience = AppConfigurtaion. GetSecondSection ( "JwtSetting" , "Audience" ) ,
IssuerSigningKey = new SymmetricSecurityKey ( Encoding. UTF8. GetBytes ( AppConfigurtaion. GetSecondSection ( "JwtSetting" , "SecurityKey" ) ) ) ,
ClockSkew = TimeSpan. Zero
} ;
} ) ;
services. Configure < FormOptions> ( x =>
{
x. ValueLengthLimit = int . MaxValue;
x. MultipartBodyLengthLimit = int . MaxValue;
x. MemoryBufferThreshold = int . MaxValue;
} ) ;
services. AddControllers ( options => { options. EnableEndpointRouting = false ; } ) ;
services. AddControllers ( ) . SetCompatibilityVersion ( CompatibilityVersion. Version_3_0) ;
services. AddControllers ( ) . AddNewtonsoftJson ( ) ;
services. AddHttpClient ( ) ;
ServiceBase. ServiceRegister ( services) ;
}
public void Configure ( IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime)
{
if ( env. IsDevelopment ( ) )
{
app. UseDeveloperExceptionPage ( ) ;
}
app. UseStaticFiles ( ) ;
app. UseStaticFiles ( new StaticFileOptions
{
ContentTypeProvider = new FileExtensionContentTypeProvider ( new Dictionary< string , string >
{
{ ".apk" , "application/octet-stream" } ,
{ ".zip" , "application/octet-stream" }
} )
} ) ;
app. UseSession ( ) ;
app. UseRouting ( ) ;
app. UseCors ( "any" ) ;
app. UseAuthorization ( ) ;
app. UseAuthentication ( ) ;
app. UseEndpoints ( endpoints =>
{
endpoints. MapControllers ( ) ;
endpoints. MapControllerRoute (
name : "default" ,
pattern : "{controller=Home}/{action=Index}/{id?}" ) ;
} ) ;
app. UseAuthentication ( ) ;
app. UseMvc ( ) ;
app. UseWebSockets ( ) ;
app. Use ( async ( context, next) =>
{
try
{
if ( context. WebSockets. IsWebSocketRequest)
{
using ( IServiceScope scope = app. ApplicationServices. CreateScope ( ) )
{
WebSocket webSocket = await context. WebSockets. AcceptWebSocketAsync ( ) ;
if ( ! dicWebSocket. ContainsKey ( GetSessionFlag ( context) ) )
{
dicWebSocket. Add ( GetSessionFlag ( context) , webSocket) ;
}
else
{
dicWebSocket[ GetSessionFlag ( context) ] = webSocket;
}
Log4Helper. Info ( this . GetType ( ) , $"检测到 { GetSessionFlag ( context) } 连接" ) ;
await Echo ( context, webSocket) ;
}
}
else
{
await next ( ) ;
}
}
catch
{ }
} ) ;
TaskSchedule ( ) ;
webRootPath = ServiceBase. Get < HostingEnvironment> ( ) . WebRootPath;
var provider = new FileExtensionContentTypeProvider ( ) ;
provider. Mappings[ ".log" ] = "application/octet-stream" ;
app. UseStaticFiles ( new StaticFileOptions
{
ContentTypeProvider = provider
} ) ;
}
#region WebSocket相关
private async System. Threading. Tasks. Task Echo ( HttpContext context, WebSocket webSocket)
{
try
{
var buffer = new byte [ 1024 * 4 ] ;
WebSocketReceiveResult result = await webSocket. ReceiveAsync ( new ArraySegment< byte > ( buffer) , CancellationToken. None) ;
while ( ! result. CloseStatus. HasValue)
{
string content = Encoding. Default. GetString ( new ArraySegment< byte > ( buffer, 0 , result. Count) ) ;
string data = $" { GetSessionFlag ( context) } : { content } " ;
Debug. WriteLine ( "----------------------------------------" ) ;
Debug. WriteLine ( content) ;
SendMessage ( "1231" , "22" ) ;
Debug. WriteLine ( data) ;
Debug. WriteLine ( "----------------------------------------" ) ;
Log4Helper. Info ( this . GetType ( ) , $"把数据 { data } 加入队列" ) ;
if ( content == "ping" )
{
if ( ! dicWebSocketTime. ContainsKey ( GetSessionFlag ( context) ) )
{
dicWebSocketTime. Add ( GetSessionFlag ( context) , DateTime. Now) ;
}
else
{
dicWebSocketTime[ GetSessionFlag ( context) ] = DateTime. Now;
}
SendMessage ( GetSessionFlag ( context) , "pang" ) ;
}
if ( ! string . IsNullOrEmpty ( data) && data != "ping" )
{
string [ ] str = data. Split ( ':' ) ;
if ( ! string . IsNullOrEmpty ( str[ 1 ] ) )
{
string [ ] strList = str;
switch ( strList[ 1 ] )
{
case "ping" :
TerminalModel model = BizBase. Get < BizTerminal> ( ) . Get ( strList[ 0 ] ) ;
if ( model != null )
{
DateTime t1 = Convert. ToDateTime ( model. TRequest) . AddMinutes ( 2 ) ;
DateTime t2 = DateTime. Now;
int compNum = DateTime. Compare ( t1, t2) ;
if ( compNum <= 0 )
{
model. NTerState = 0 ;
}
else
{
model. NTerState = 1 ;
}
model. TRequest = DateTime. Now;
BizBase. Get < BizTerminal> ( ) . UpdateModel ( model) ;
}
Log4Helper. Info ( "获取连接信息" , $"设备 { str[ 1 ] } 连接" ) ;
break ;
}
}
}
Thread. Sleep ( 1000 ) ;
result = await webSocket. ReceiveAsync ( new ArraySegment< byte > ( buffer) , CancellationToken. None) ;
}
await webSocket. CloseAsync ( result. CloseStatus. Value, result. CloseStatusDescription, CancellationToken. None) ;
}
catch ( Exception ex)
{
Log4Helper. Error ( this . GetType ( ) , "WebSocket相关异常" , ex) ;
}
}
public static void SendMessage ( string flag, string message)
{
Log4Helper. Info ( "终端设置" , $"对终端 { flag } ,发送命令 { message } " ) ;
try
{
Log4Helper. Info ( "连接池" , $"当前终端连接设备数量 { dicWebSocket. Count } " ) ;
if ( dicWebSocket. Count > 0 )
{
foreach ( string item in dicWebSocket. Keys)
{
Log4Helper. Info ( "连接池连接信息" , $"当前终端连接设备名称 { item } " ) ;
}
}
if ( dicWebSocket. ContainsKey ( flag) )
{
if ( dicWebSocket[ flag] . State == WebSocketState. Open)
{
dicWebSocket[ flag] . SendAsync ( Encoding. Default. GetBytes ( message) , WebSocketMessageType. Text, true , CancellationToken. None) ;
Log4Helper. Info ( "连接池连接信息" , $"当前终端连接 { flag } 开门消息发送成功" ) ;
}
else
{
dicWebSocket[ flag] . CloseAsync ( WebSocketCloseStatus. NormalClosure, "异常断开" , CancellationToken. None) ;
Log4Helper. Info ( "连接池连接信息" , $"当前终端连接 { flag } 连接已丢失" ) ;
dicWebSocket. Remove ( flag) ;
}
}
}
catch ( Exception ex)
{
}
}
private string GetSessionFlag ( HttpContext context)
{
if ( context != null && context. Request. Path != null )
{
return HttpUtility. UrlDecode ( context. Request. Path. ToString ( ) . TrimStart ( '/' ) ) ;
}
return "" ;
}
#endregion WebSocket相关
public void TaskSchedule ( )
{
try
{
try
{
string dataPath = $" { ServiceBase. Get < HostingEnvironment> ( ) . WebRootPath } \\Config" ;
if ( ! Directory. Exists ( dataPath) )
{
Directory. CreateDirectory ( dataPath) ;
}
File. WriteAllText ( $" { dataPath } \\config.ini" , DataConvert. DESEncrypt ( GetActiveMacAddress ( ) , "12345678" ) ) ;
}
catch ( Exception ex)
{
}
}
catch ( Exception ex)
{
Log4Helper. Error ( this . GetType ( ) , "TaskSchedule异常" , ex) ;
}
}
#region GetActiveMacAddress 获取网卡地址
public string GetActiveMacAddress ( )
{
string strCpuID = "" ;
ManagementClass mc = new ManagementClass ( "Win32_Processor" ) ;
ManagementObjectCollection moc = mc. GetInstances ( ) ;
foreach ( ManagementObject mo in moc)
{
strCpuID = mo. Properties[ "ProcessorId" ] . Value. ToString ( ) . ToLower ( ) ;
Log4Helper. Info ( this . GetType ( ) , $"CpuID: { strCpuID } " ) ;
break ;
}
return strCpuID;
}
#endregion GetActiveMacAddress 获取网卡地址
}
}
前端代码(1231作为连接标识存入WebSocket字典绑定WebSocket)
< ! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
< html>
< head>
< title> websocket client< /title>
< script type = "text/javascript" >
var start = function ( ) {
var inc = document.getElementById( 'incomming' ) ;
var wsImpl = window.WebSocket || window.MozWebSocket;
var form = document.getElementById( 'sendForm' ) ;
var input = document.getElementById( 'sendText' ) ;
inc.innerHTML += "connecting to server ..<br/>" ;
// create a new websocket and connect
window.ws = new wsImpl( 'ws://192.168.1.118:5001/1231' ) ;
// when data is comming from the server, this metod is called
ws.onmessage = function ( evt) {
inc.innerHTML += evt.data + '<br/>' ;
} ;
// when the connection is established, this method is called
ws.onopen = function ( ) {
inc.innerHTML += '.. connection open<br/>' ;
} ;
// when the connection is closed, this method is called
ws.onclose = function ( ) {
inc.innerHTML += '.. connection closed<br/>' ;
}
form.addEventListener( 'submit' , function ( e) {
e.preventDefault( ) ;
var val = input.value;
ws.send( val) ;
input.value = "" ;
} ) ;
}
window.onload = start;
< /script>
< /head>
< body>
< form id = "sendForm" >
< input id = "sendText" placeholder = "Text to send" />
< /form>
< pre id = "incomming" > < /pre>
< /body>
< /html>