前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >asp dotnet core 通过图片统计 csdn 用户访问

asp dotnet core 通过图片统计 csdn 用户访问

作者头像
林德熙
发布于 2022-08-04 09:22:29
发布于 2022-08-04 09:22:29
1.8K00
代码可运行
举报
文章被收录于专栏:林德熙的博客林德熙的博客
运行总次数:0
代码可运行

在 csdn 的访问统计里面,只能用 csdn 提供的访问统计,因为在 csdn 中不支持在博客加上 js 代码,也就是无法使用友盟等工具统计。 通过在 asp dotnet core 创建一个图片链接的方式,将这个链接作为图片放在 csdn 的博客,可以在链接被访问的时候统计用户访问

新建一个 asp dotnet core 项目,在自己的 controler 里面添加一个方法,这个方法的访问链接是 xx.png 假装这是一张图片,请看代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    [Route("api/[controller]")]
    [ApiController]
    public class ImageController : ControllerBase
    {
    	[Route("csdn/Image.png")]
        [HttpGet]
        public FileResult GetCSDNImage()
        {
        	// 忽略代码
        }
    }

在 csdn 上通过访问我的域名对应的链接就可以调用 GetCSDNImage 方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
![] (http://bulleimage.service.walterlv.com/api/image/csdn/image.png )

注意路由的命名要清真一点,我本来是用来做广告的,于是命名为广告,然而发现在 csdn 无法被访问到,原因请看 asp dotnet core 图片在浏览器没访问可能原因

通过在 GetCSDNImage 返回一张图片,同时按照这个方法调用的次数就可以用来统计用户的访问了

缓存图片

在 GetCSDNImage 需要返回图片才可以用来假装这是一个静态图片的链接

我将一张图片放在输出文件夹,做法就是在解决方案添加一张图片,右击属性设置复制输出到文件夹

在 Startup 的 ConfigureServices 里面添加内存缓存

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        public void ConfigureServices(IServiceCollection services)
        {
        	// 忽略其他代码
            services.AddMemoryCache(); // 添加这一行代码就可以使用内存缓存

            services.AddControllers()
                .AddNewtonsoftJson();
            // 忽略代码
        }

修改 ImageController 在构造注入缓存 IMemoryCache 方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        public ImageController(IMemoryCache memoryCache)
        {
            _cache = memoryCache;
        }

        private IMemoryCache _cache;

这样就可以在 GetCSDNImage 方法里面使用缓存了

在使用缓存之前需要读取输出文件夹里面的图片,我添加一个方法用来读取输出文件夹里面的图片。在 asp dotnet core 中,很多都是使用指定静态的文件夹作为静态资源的文件夹,直接通过输出文件夹读取的比较少。但是设置一个静态文件夹是另外的知识,本文就直接通过输出文件夹读取

使用 Path.GetDirectoryName(Assembly.GetCallingAssembly().Location) 可以拿到输出文件夹,详细请看dotnet 获取程序所在路径的方法

使用下面代码就可以读取图片文件作为字节了,建议只读取一次,解决多线程访问文件的问题

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        private byte[] GetImage()
        {
            var file = Path.Combine(Path.GetDirectoryName(Assembly.GetCallingAssembly().Location), "Image.png");

            return System.IO.File.ReadAllBytes(file);
        }

在 GetCSDNImage 方法里面通过缓存,判断如果缓存里面没有值就从文件读取图片,如果有值就直接从内存返回

如果这段代码是需要我自己写,可能要写几天,因为还存在了多线程访问的问题,如果一开始不存在值,那么就需要创建值,如何作为第一次创建值的时候,刚好多个线程进来,只有一个线程创建等问题。还好微软提供的缓存里面有这样的方法 GetOrCreate 方法,尝试从内存获取,如果获取不到就创建,在这个方法里面第一个参数是传入 key 第二个参数就是传入如何创建的方法。在缓存中就通过 key 来获取或设置值,用法和字典差不多

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
            var file = _cache.GetOrCreate("Image", entry => GetImage());

现在拿到了值,可以通过 File 方法返回,注意在返回的时候添加 content type 说这是一张图片

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        public FileResult GetCSDNImage()
        {     
             var file = _cache.GetOrCreate("Image", entry => GetImage());
      
             return File(file, "image/png");
        }

统计用户访问

我不会告诉大家如何去创建数据库去存放用户访问的数据,因为这些需要的知识点有些多,本文的统计用户访问只是通过一个简单的静态变量获取,不考虑并发的问题

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        public FileResult GetCSDNImage()
        {     
        	Count++;

        	Console.WriteLine($"总共有{Count}访问");

             
            // 忽略其他代码
        }

        private static int Count { set; get; }

这样就可以完成了统计用户的访问了,同时代码也很少。我还需要用户的 IP 和使用什么浏览器,于是需要添加一点代码

我的网站是通过 frp 让用户访问,需要从 Frp 获取用户真实 IP 地址用法有点复杂

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        private static bool TryGetUserIpFromFrp(HttpRequest httpContextRequest, out StringValues ip)
        {
            return httpContextRequest.Headers.TryGetValue("X-Forwarded-For", out ip);
        }

上面这个方法就可以从 HttpRequest 拿到从 frp 获取的用户 ip 地址

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        public FileResult GetCSDNImage()
        {
        	// 忽略代码

            if (TryGetUserIpFromFrp(HttpContext.Request, out var ip))
            {
               
            }

        	// 忽略代码
        }

获取用户的浏览器使用 Headers 里面的 User-Agent 可以拿到

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        public FileResult GetCSDNImage()
        {
        	// 忽略代码

            if (HttpContext.Request.Headers.TryGetValue("User-Agent", out var userAgent))
            {
               
            }

        	// 忽略代码
        }

将这些值合并输出

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        [Route("csdn/Image.png")]
        [HttpGet]
        public FileResult GetCSDNImage()
        {
            Count++;

            StringBuilder str = new StringBuilder();
            str.Append(DateTime.Now);
            str.Append(" ");
            str.Append("用户访问 ");

            Console.WriteLine(GetUserId());
            Console.WriteLine("用户id =" + HttpContextAccessor.HttpContext.Request.HttpContext.Session.Id);

            if (TryGetUserIpFromFrp(HttpContextAccessor.HttpContext.Request, out var ip))
            {
                str.Append("用户Ip=");
                str.Append(ip);
                str.Append(" ");
            }

            str.Append($"总共有{Count}访问");

            if (HttpContext.Request.Headers.TryGetValue("User-Agent", out var userAgent))
            {
                str.Append("\r\n");
                str.Append("当前用户浏览器");
                str.Append(userAgent);
            }

            Console.WriteLine(str);

            var file = _cache.GetOrCreate("Image", entry => GetImage());

            return File(file, "image/png");
        }

我将这个图片放在 csdn 的博客,运行服务在用户访问的时候可以看到下面的输出

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2019/5/26 11:39:24 用户访问 用户Ip=58.209.53.254 总共有13访问
当前用户浏览器Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36

如果要分析什么时候的用户访问有多少,就需要添加数据库,这些需要的知识有点多,本文就不告诉大家

代码很简单,都放在 github

dotnet 获取程序所在路径的方法

asp dotnet core 从 Frp 获取用户真实 IP 地址

asp dotnet core 图片在浏览器没访问可能原因

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Linux系统编程:进程控制(创建,终止,等待)
1.在fork返回之前,创建了子进程的 PCB数据结构,以及拷贝了一份父进程的地址空间和页表;此时页表是出于只读,一旦修改就会写实拷贝;
啊QQQQQ
2025/02/20
1360
Linux系统编程:进程控制(创建,终止,等待)
【Linux篇章】踏入 Linux 进程控制的奇幻迷宫,解锁系统调度奥秘(秒懂版)
因此;我们就可以把fork后理解成分流:返回的id=0的子进程是一个流而id=子进程pid 父进程是一个流;各自干各自的事。
羑悻的小杀马特.
2025/04/15
320
【Linux篇章】踏入 Linux 进程控制的奇幻迷宫,解锁系统调度奥秘(秒懂版)
【Linux】进程控制
我们在前面的文章中多次使用过fork函数,我们在这里再来简单概括一下进程的创建 fork可以在已有的进程中创建出一个新进程,老进程为父进程,新进程为子进程
s-little-monster
2025/02/14
550
【Linux】进程控制
详谈 Linux进程控制(看这一篇就够了)
本文将系统介绍进程控制的基本要素,包括进程创建, 进程终止, 进程等待, 进程替换等方面。深入理解进程创建的相关知识, 帮助更好的构建知识架构!
用户11317877
2024/12/20
1500
详谈 Linux进程控制(看这一篇就够了)
Linux之进程控制
此外还可以通过调用fork函数创建子进程,子进程和父进程共享fork之后的代码,可以采用对fork返回值进行判断的办法来让父子进程分别执行后续代码的一部分。
始终学不会
2023/04/17
8440
Linux之进程控制
【Linux篇】进程控制
在linux中fork函数是非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。
_孙同学
2025/03/21
880
【Linux篇】进程控制
Linux进程控制
返回值:自进程中返回0,父进程返回子进程id,出错返回-1。 进程拥有独立性,fork之后就变成了两个程序,父子进程共享后边的代码。 那么为什么给父进程返回的就是子进程的pid,而给子进程返回的就是0呢? 就好比孩子只能有一个亲生的父亲,而一个父亲可以拥有很多亲生孩子,每个孩子都是独立不同的。 fork函数是在什么时候创建的子进程呢?
有礼貌的灰绅士
2023/03/28
2.9K0
Linux进程控制
Linux之进程控制
退出码是用来标识一个进程任务执行结果的情况。因为成功只有一种情况,而失败的情况很多,因此,一般情况下0表示执行成功,非0表示执行失败。非0的数字不同,所表示的错误不同。系统对于退出码一般都有着相应的文字藐视,当然我们也可以自定义,也可以直接使用系统给定的映射关系。(例如,strerror这个函数)
摘星
2023/10/15
2030
Linux之进程控制
【Linux】万字解读<进程控制>:创建&中止&等待&替换
YY的秘密代码小屋
2024/09/11
1240
【Linux】万字解读<进程控制>:创建&中止&等待&替换
【Linux】探索进程控制奥秘,解锁高效实战技巧
因为字符串具有常量属性,字符常量不可被修改。这里的问题是字符串为什么会有常量属性呢?
用户11316056
2024/10/16
660
【Linux】探索进程控制奥秘,解锁高效实战技巧
【Linux】进程控制
若父子进程数据都不修改,则父子进程指向同一个物理地址, 若子进程数据修改,则拷贝一个物理空间,将新的地址填到子进程对应的页表中,使子进程重新映射,访问到新的空间 进程的内核数据结构,父子各自有一套,彼此双方互不影响, 代码和数据通过写时拷贝的反方式,实现分开
lovevivi
2023/04/28
2K0
【Linux】进程控制
【Linux】Linux进程控制——进程创建、进程终止及进程等待详解
在Linux中fork函数时非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。
P_M_P
2024/08/15
3800
【Linux】Linux进程控制——进程创建、进程终止及进程等待详解
Linux进程控制
hello,my friend!今天,我们要开始学习新的内容了--->进程控制,进程控制涉及到操作系统如果管理和控制运行在计算机系统内的进程。我们将从fork函数,Linux进程退出,Linux进程等待,Linux进程替换等方面学习。那么接下来我们就开始敲黑板了!!
破晓的历程
2024/06/24
1220
Linux进程控制
Linux系统-进程控制
Linux进程控制 零、前言 一、进程创建 1、fork函数 2、fork返回值 写时拷贝 3、fork用法 4、fork失败 二、进程终止 1、退出码 2、退出方法 1) 调用_exit函数 2)调用exit函数 3)main函数return 4)异常退出 3、理解终止 三、进程等待 1、等待方法 2、获取status 3、理解等待 四、进程替换 1、替换原理 2、替换方法 五、实现简易shell 零、前言 前篇我们讲解学习了关于进程的概念知识,本章主要讲解关于进程的控制,深入学习进程 一、进程创建
用户9645905
2022/11/30
1.5K0
Linux系统-进程控制
进程控制
在linux中fork函数是非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。
海盗船长
2020/08/27
7410
【linux】进程等待与进程替换
任何子进程,在退出的情况下,一般必须要被父进程进行等待。进程在退出的时候,如果父进程不管不顾,退出进程,状态Z(僵尸状态),内存泄漏
用户11029103
2024/11/16
1700
【linux】进程等待与进程替换
Linux进程控制【创建、终止、等待】
进程 创建后,需要对其进行合理管理,光靠 OS 是无法满足我们的需求的,此时可以运用 进程 控制相关知识,对 进程 进行手动管理,如创建 进程、终止 进制、等待 进程 等,其中等待 进程 可以有效解决僵尸 进程 问题
北 海
2023/07/01
3780
Linux进程控制【创建、终止、等待】
【Linux】深入理解进程控制:从创建到终止和进程等待
fork 函数是 Unix/Linux 系统中用于创建新进程的系统调用。调用 fork 后,当前进程(父进程)会被复制,创建出一个新的进程(子进程)。 fork函数特点:
用户11305458
2024/11/21
2120
【Linux】深入理解进程控制:从创建到终止和进程等待
Linux进程编程
功能:创建一个与原来进程几乎完全相同的进程,即两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。一个进程调用fork函数后,系统先给新的进程分配资源,例如,存储数据和代码的空间。然后把原来的进程所有值都复制到新的进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。
Marigold
2022/06/17
7.9K0
Linux进程编程
【Linux】开始掌握进程控制吧!
送给大家一句话: 我并不期待人生可以一直过得很顺利,但我希望碰到人生难关的时候,自己可以是它的对手。—— 加缪
叫我龙翔
2024/03/30
1220
【Linux】开始掌握进程控制吧!
推荐阅读
相关推荐
Linux系统编程:进程控制(创建,终止,等待)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档