黄色电影一区二区,韩国少妇自慰A片免费看,精品人妻少妇一级毛片免费蜜桃AV按摩师 ,超碰 香蕉

ASP.NET Core快速入門之實(shí)戰(zhàn)篇

asp.net core快速入門之實(shí)戰(zhàn)篇

 

no1 留言板(mysql的使用)

演示:http://haojima.net
這個(gè)功能很簡(jiǎn)單。就是對(duì)數(shù)據(jù)庫的寫入和展示。如果在windows下,相信大家分分鐘都可以搞定。而初次接觸.net core + mysql可能需要注意些細(xì)節(jié)。

首先打開vs2017新建一個(gè)asp.net core項(xiàng)目(選web應(yīng)用程序),然后nuget 導(dǎo)入microsoft.entityframeworkcore.tools 1.1.1和mysql.data.entityframeworkcore 8.0.8-dmr。
然后新建一個(gè)dbcontext類。

public class datacontext : dbcontext
{
  //【注意】連接字符串一定要加 sslmode=none 
  string str = @"data source=;database=;user id=;password=;pooling=true;charset=utf8;port=3306;sslmode=none";
  protected override void onconfiguring(dbcontextoptionsbuilder optionsbuilder) =>
      optionsbuilder.usemysql(str);

  //下面就可以添加要加入數(shù)據(jù)庫的實(shí)體了
  //public dbset<message> messages { get; set; }
}

到此為止,我們已經(jīng)可以利用ef core直接連接mysql進(jìn)行增刪改查操作了。注意:需要導(dǎo)入命名空間using microsoft.entityframeworkcore; using mysql.data.entityframeworkcore.extensions;

當(dāng)然。你會(huì)說,連接字符串不能硬編碼到代碼里面。我們也可以放配置文件。appsettings.json

{
"logging": {
  "includescopes": false,
  "loglevel": {
    "default": "warning"
  }
},
"connectionstrings": { "sqlserverconnection": "data source=;database=;user id=;password=;pooling=true;charset=utf8;port=3306;sslmode=none" }
}

然后把上面的硬編碼注釋掉。在startup.cs文件的configureservices方法添加

var connection = configuration.getconnectionstring("sqlserverconnection");
services.adddbcontext<datacontext>(options => options.usemysql(connection));

【注意】項(xiàng)目名稱和路徑最好不要有中文,不然會(huì)出現(xiàn)些亂七八糟的問題。

【完整代碼】:https://github.com/zhaopeiym/blogdemocode/tree/master/messageboard

 

no2 聊天室(websocket的使用)

演示:http://socket.haojima.net

websocket是html5新增的一個(gè)很酷的技術(shù)。下面我們簡(jiǎn)單講解下這個(gè)很酷的技術(shù)

var socket = new websocket(url);//創(chuàng)建 websocket 對(duì)象

創(chuàng)建了一個(gè)websocket對(duì)象后會(huì)觸發(fā)打開連接事件:

socket.onopen = function(){  }

除了onopen事件,還有其他三個(gè)事件:

socket.onmessage  //客戶端接收服務(wù)端數(shù)據(jù)時(shí)觸發(fā)
socket.onerror    //通信發(fā)生錯(cuò)誤時(shí)觸發(fā)
socket.onclose    //連接關(guān)閉時(shí)觸發(fā)

另外還有兩個(gè)方法:

socket.send()   //使用連接發(fā)送數(shù)據(jù)
socket.close()  //關(guān)閉連接

最后還有四個(gè)連接狀態(tài)屬性:

socket.readystate
0 - 表示連接尚未建立。
1 - 表示連接已建立,可以進(jìn)行通信。
2 - 表示連接正在進(jìn)行關(guān)閉。
3 - 表示連接已經(jīng)關(guān)閉或者連接不能打開。

整個(gè)websocket常用功能知識(shí)點(diǎn)就四個(gè)事件、兩個(gè)方法、四種狀態(tài)。簡(jiǎn)單吧,下面我們看看asp.net core后臺(tái)的配合:

后臺(tái)添加一個(gè)sockethandler類,并添加一個(gè)靜態(tài)方法map:

/// <summary>
/// 請(qǐng)求
/// </summary>
/// <param name="app"></param>
public static void map(iapplicationbuilder app)
{
  app.usewebsockets(); //【注意】需要 nuget   導(dǎo)入 microsoft.aspnetcore.websockets.server
  app.use(acceptor);
}

然后新增對(duì)應(yīng)的acceptor方法:

/// <summary>
/// 接收請(qǐng)求
/// </summary>
/// <param name="httpcontext"></param>
/// <param name="n"></param>
/// <returns></returns>
static async task acceptor(httpcontext httpcontext, func<task> n)
{

需要在startup.cs類里面的configure方法里面加入

app.map("/ws", sockethandler.map);   //傳入我們剛才新建的靜態(tài)方法map

現(xiàn)在為止,基本的類和配置已經(jīng)完成。

我們主要操作,是在acceptor方法里面接收和發(fā)送消息。

//建立連接
var socket = await httpcontext.websockets.acceptwebsocketasync();
//等待接收數(shù)據(jù)
await socket.receiveasync(new arraysegment<byte>(buffer), cancellationtoken.none);
//發(fā)送消息
await socket.sendasync(arraysegment, websocketmessagetype.text, true, cancellationtoken.none);

后臺(tái)關(guān)鍵代碼也就這三句,建立連接、等待接收、發(fā)送消息。
不過這里有一點(diǎn)需要理解。建立連接后,可以接收任意多次客戶端消息。所以receiveasync等待接收這里需要死循環(huán)接收消息,直到連接斷開。(不用擔(dān)心真的死循環(huán),沒有消息發(fā)送的時(shí)候,代碼會(huì)阻塞在那里等待消息)

【完整實(shí)現(xiàn)】:https://github.com/zhaopeiym/chatroom

 

no3 找工作(anglesharp的使用)

演示:http://job.haojima.net
對(duì)于爬蟲抓包,我相信大家初次接觸都非常的熱衷于此。我也不例外。
那么在asp.net core下面是否也有這樣的插件呢?答案是肯定的。
http://www.cnblogs.com/linezero/p/5599611.html htmlagilitypack html解析(感謝博主對(duì).net core的貢獻(xiàn))。不過xpath用起來超級(jí)惡心。
之前在.net下面有一款jumony http://www.cnblogs.com/ivony/p/3447536.html(博客園大牛寫的)。支持css選擇和linq查詢。簡(jiǎn)直不要太爽??墒遣恢С?net core。(本人試了下遷移.net core,發(fā)現(xiàn)很多類在.net core沒有實(shí)現(xiàn))
最后還是到了一款支持.net core的解析組件。并可以媲美jumony,同樣支持css選擇和linq查詢。那就是anglesharp。
新建項(xiàng)目,nuget 安裝 anglesharp。然后以下簡(jiǎn)單使用:

using (httpclient http = new httpclient())
{
  var htmlstring = await http.getstringasync(url);
  htmlparser htmlparser = new htmlparser();
  var jobinfos = htmlparser.parse(htmlstring)
      .queryselectorall(".newlist_list_content table")
      .where(t => t.queryselectorall(".zwmc a").firstordefault() != null)
      .select(t => new jobinfo()
      {
          positionname = t.queryselectorall(".zwmc a").firstordefault().textcontent,
          corporatename = t.queryselectorall(".gsmc a").firstordefault().textcontent,
          salary = t.queryselectorall(".zwyx").firstordefault().textcontent,
          workingplace = t.queryselectorall(".gzdd").firstordefault().textcontent,
      .tolist();
  return jobinfos;
}

看到?jīng)]有,就像jq一樣解析html。如果你說不爽我都不信。

【完整實(shí)現(xiàn)】:https://github.com/zhaopeiym/jobwanted

 

部署多個(gè)站點(diǎn)

以上,這些項(xiàng)目都比較簡(jiǎn)單。關(guān)鍵技術(shù)點(diǎn)和難點(diǎn)都進(jìn)行的分析。我相信大家都可以動(dòng)起手練習(xí)起來了。
不過有個(gè)問題,前面我們只說了部署一個(gè)應(yīng)用程序。如果是多個(gè)該怎么部署呢?
首先我們把多個(gè)程序發(fā)布包放到服務(wù)器上。
然后修改nginx的配置文件/etc/nginx/conf.d/default.conf

server {
  listen 80;
  server_name www.haojima.net;           #對(duì)應(yīng)的域名
  root /home/projects/messagboard;       #程序路徑
  location / {
      proxy_pass http://localhost:5000;  #內(nèi)網(wǎng)端口
      proxy_http_version 1.1; 
      proxy_set_header upgrade $http_upgrade;
      proxy_set_header connection keep-alive;
      proxy_set_header host $host;
      proxy_cache_bypass $http_upgrade;
      proxy_set_header x-real-ip $remote_addr;
      
      proxy_set_header upgrade $http_upgrade;   
  }
}

有幾個(gè)程序就添加幾個(gè)server,不過需要修改你解析到的域名、程序路徑和內(nèi)網(wǎng)對(duì)應(yīng)的端口(看配置里的注釋) 。
然后修改supervisor的配置文件/etc/supervisor/conf.d/supervisord.conf

[program:messageboard]
command=dotnet messageboard.dll        ; 運(yùn)行程序的命令
directory= /home/projects/messagboard/ ; 命令執(zhí)行的目錄
autorestart=true                    ; 程序意外退出是否自動(dòng)重啟
stderr_logfile=/var/log/webapplication1.err.log ; 錯(cuò)誤日志文件
stdout_logfile=/var/log/webapplication1.out.log ; 輸出日志文件
environment=aspnetcore_environment=production ; 進(jìn)程環(huán)境變量
user=root ; 進(jìn)程執(zhí)行的用戶身份
stopsignal=int

有幾個(gè)程序就往下復(fù)制幾份program。需要修改program名稱,只要名稱不重復(fù)就可以。然后修改 運(yùn)行程序的命令 對(duì)應(yīng)的dll和命令執(zhí)行的目錄(看配置文件的注釋)。
如此就可以部署多個(gè)程序了。

開始我還以為是在域名解析的時(shí)候,解析ip + 端口。原來是多個(gè)域名解析到同一個(gè)ip,然后nginx在內(nèi)部做域名和內(nèi)網(wǎng)端口分發(fā)。

 

一些其它的細(xì)節(jié)

部署阿里云

我們?cè)趌inux的防火墻開放了端口,發(fā)現(xiàn)在外面還是訪問不了(可以telnet ip 端口 來測(cè)試)。有可能是阿里云攔截了。https://help.aliyun.com/document_detail/25471.html 在安全組添加某端口哪些ip可以訪問。

mysql的客戶端

對(duì)于mysql,我們安裝好之后總不能每次命令操作吧。在windows下面有個(gè)客戶端navicat可以方便管理mysql。navicat

獲取ip

用了nginx后發(fā)現(xiàn)取不到瀏覽器ip了。那是因?yàn)槲覀兂绦蚨际菫g覽器訪問nginx,然后nginx轉(zhuǎn)發(fā)內(nèi)網(wǎng)程序端口。所以取到的ip都是內(nèi)網(wǎng)本機(jī)ip。如果需要取瀏覽器ip需要在nginx配置

server {
  listen 80;
  server_name www.haojima.net;
  root /home/projects/messagboard;
  location / {
      proxy_pass http://localhost:5000;
      proxy_http_version 1.1; 
      proxy_set_header upgrade $http_upgrade;
      proxy_set_header connection keep-alive;
      proxy_set_header host $host;
      proxy_cache_bypass $http_upgrade;
      proxy_set_header x-real-ip $remote_addr;     # 新添加
  }
}

然后代碼里面取ip:

var ip = httpcontext.request.headers["x-real-ip"].firstordefault();

websocket在nginx的配置

上面我們寫的websocket直接運(yùn)行發(fā)現(xiàn)沒有任何問題,可是部署在nginx去跑不起來了。那是因?yàn)樾枰猲ginx支持websocket,需要配置。http://nginx.org/en/docs/http/websocket.html

server {
  listen 80;
  server_name job.haojima.net;
  root /home/projects/jobwanted;
  location / {
      proxy_pass http://localhost:5002;
      proxy_http_version 1.1;
      proxy_set_header upgrade $http_upgrade;
      proxy_set_header connection keep-alive;
      proxy_set_header host $host;
      proxy_cache_bypass $http_upgrade;
      proxy_set_header x-real-ip $remote_addr;
      proxy_set_header upgrade $http_upgrade;     # 新增
      #proxy_set_header connection "upgrade";      # 新增 
      proxy_set_header connection $http_connection;  #ws和post同時(shí)使用  https://github.com/aspnet/kestrelhttpserver/issues/1263
  }
}

websocket心跳

經(jīng)過上面的配置,我們的websocket在nginx上跑起來了。萬分歡喜的我們,發(fā)現(xiàn)一分鐘不發(fā)消息就自動(dòng)掉線了。郁悶至極到頭大。細(xì)心的同學(xué)通過上面的鏈接資料其實(shí)已經(jīng)有說明:

by default, the connection will be closed if the proxied server does not transmit any data within 60 seconds. this timeout can be increased with the proxy_read_timeout directive. alternatively, the proxied server can be configured to periodically send websocket ping frames to reset the timeout and check if the connection is still alive.

nginx給出了兩種解決方案。第一種,修改proxy_read_timeout (默認(rèn)60秒)。第二種,瀏覽器客戶端定時(shí)發(fā)送心跳包(時(shí)間要短于proxy_read_timeout)。

我使用的是第二種方式。

第一種雖然簡(jiǎn)單粗暴,但是時(shí)間再長(zhǎng)也是一個(gè)值,還是會(huì)有超時(shí)的可能。再者,誰能保證瀏覽器端不會(huì)new 很多個(gè)websocket出來搗蛋。

第二種方式,瀏覽器定時(shí)發(fā)送一條消息,內(nèi)容和后臺(tái)約定下。如發(fā)送“心跳”,然后后臺(tái)接收消息是,判斷如果是“心跳”則不做任何處理。

中文編碼

在做“找工作”爬前程無憂的數(shù)據(jù)時(shí),發(fā)現(xiàn)他們使用的gbk編碼。而在.net core中默認(rèn)不支持這種格式,導(dǎo)致取到的數(shù)據(jù)都是亂碼。我們需要nuget安裝system.text.encoding.codepages。然后在startup.cs的configure里面注冊(cè):

encoding.registerprovider(codepagesencodingprovider.instance);//注冊(cè)編碼提供程序

使用:

var htmlbytes = await http.getbytearrayasync(url);
var htmlstring = encoding.getencoding("gbk").getstring(htmlbytes);

asp.net core 端口分配

asp.net core 默認(rèn)端口都是5000。那么我們運(yùn)行第二個(gè)程序的時(shí)候就會(huì)提示5000端口被占用。這個(gè)時(shí)候,我們就需要為每個(gè)程序分配不同的端口了。
在根目錄新建一個(gè)json文件hosting.json

{
"server.urls": "http://*:5002"
}

在program.cs文件修改

public static void main(string[] args)
{
  var config = new configurationbuilder()
        .setbasepath(directory.getcurrentdirectory())
        .addjsonfile("hosting.json", optional: true)
        .build();

  var host = new webhostbuilder()
      .usekestrel()
      .useconfiguration(config)
      .usecontentroot(directory.getcurrentdirectory())
      .useiisintegration()
      .usestartup<startup>()
      .useapplicationinsights()
      .build();

  host.run();
}

爬拉勾數(shù)據(jù)

在爬拉勾網(wǎng)的時(shí)候沒有搞定,不知道是不是因?yàn)閔ttps的原因。

using (httpclient http = new httpclient())
{
  var url = "https://www.lagou.com/zhaopin/java/?labelwords=label";
  var htmlstring = await http.getstringasync(url);
}

在.net core中報(bào)錯(cuò):an unhandled exception occurred while processing the request.
在.net 4.5 中抓到的數(shù)據(jù)是“頁面加載中...”。和瀏覽器訪問的結(jié)果不一樣。

170819搞定

https://github.com/zhaopeiym/jobwanted/blob/master/jobwanted/controllers/jobscontroller.cs#l211

//拉勾網(wǎng) 后臺(tái)檢測(cè)了user-agent、x-requested-with、referer還會(huì)檢測(cè)list_是否有參數(shù)
http.defaultrequestheaders.add("referer", "https://www.lagou.com/jobs/list_.net");
http.defaultrequestheaders.add("user-agent", "mozilla/5.0");
http.defaultrequestheaders.add("x-requested-with", "xmlhttprequest");

演示
http://haojima.net
http://socket.haojima.net
http://job.haojima.net

源碼
https://github.com/zhaopeiym/jobwanted
https://github.com/zhaopeiym/chatroom
https://github.com/zhaopeiym/blogdemocode

以上就是asp.net core快速入門之實(shí)戰(zhàn)篇的詳細(xì)內(nèi)容,更多關(guān)于asp.net core實(shí)戰(zhàn)的資料請(qǐng)關(guān)注碩編程其它相關(guān)文章!

下一節(jié):.net core 集成 kafka的步驟

asp.net編程技術(shù)

相關(guān)文章