本帖最后由 元始天尊 于 2021-7-28 23:52 编辑
小众软件常见盈利模式
这里讨论基于自身经验,欢迎补充:
- 内购盈利,用户自愿为游戏性或功能性支付,适合合规的App和游戏此类软件需要花较大代价推广
- 广告盈利,软件内嵌广告,从广告商或代理联盟赚取被动收益,此类软件需要花较大代价推广
- 任务/网赚,即通过机器刷任务或将任务代理给网赚软件用户做任务,从第三方任务平台赚取收益
- 卡密盈利,是针对账户或设备进行授权的行为,早年间的游戏经常使用该方法销售。适合特定目标人群,优点是销售简单,方便代理分类分级推广,销售较为方便且有持续收入,方便积累客户
- 一次性交付+定期维护,这种方式适合对接少量大客户,特点是一次性收入较多但持续性收入低,且有被滥用的风险。
准备工作
- 测试环境为Linux/Mac + Python3
- 开发语言包括python/html/jquery
- python3安装tornado包
此例中,后端代码不到100行,前端代码不到60行。因此功能也仅是产生一堆卡密。如果读者要实现更复杂的功能,需要自己完善。下面来讲解源码,本教程源码位于https://gitee.com/lich0/jailbroken_programming_lesson/tree/master/frontend1_faka
后端代码
class MainHandler(tornado.web.RequestHandler,tornado.tcpserver.TCPServer):
executor = ThreadPoolExecutor(serv_thread)
@tornado.gen.coroutine
def get(self): # 用于访问静态页面
global html_path
try:
path = self.request.uri
if path == "/": # 将浏览器访问默认路径导向到首页
path = "/index.html"
urlpath = html_path + path # html_path为静态网页的本机目录
with open(urlpath, 'rb') as f:
self.write(f.read())
if path.endswith('.htm') or path.endswith('.html') or path.endswith('.html'):
self.set_header("Content-Type", "text/html")
elif path.endswith('.css'):
self.set_header("Content-Type", "text/css")
elif path.endswith('.js'):
self.set_header("Content-Type", "application/x-javascript")
else:
self.set_header("Content-Type", "application/octet-stream")
self.set_status(200)
self.finish()
except:
self.write(b'null')
self.set_status(500)
self.finish()
return
@tornado.gen.coroutine # 处理多用户同时请求
def post(self): # 用于处理用户请求
try:
path = self.request.uri
func = path[1:]
output = yield self.handler(func, self.request.body) # 处理多用户同时请求
self.write(output)
self.set_status(200)
self.finish()
except:
traceback.print_exc()
self.write(b'null')
self.set_status(500)
self.finish()
return
@run_on_executor # 处理多用户同时请求
def handler(self, func, indata):
injson = json.loads(indata)
outjson = globals()[func](injson) # 根据访问路径自动调用函数
return json.dumps(outjson)
def add_card(injson): # 批量发卡
global scu
count = injson["count"]
outjson = {
"status": 0,
"msg": "",
"data": [randstr(8) for i in range(count)] # 产生count个8位卡密
}
return outjson
if __name__ == '__main__':
application = tornado.web.Application([(".*", MainHandler)])
http_server = tornado.httpserver.HTTPServer(application, decompress_request=True)
http_server.listen(serv_port)
print('服务器已启动:%d' % serv_port)
tornado.ioloop.IOLoop.instance().start() # 代码执行到此将会卡住,进入请求监听模式
前端代码
$("#add_card").click(function() { // 发卡按钮点击事件
var product = $("#product").val();
var card_count = parseInt($("#count").val());
if (isNaN(card_count)) {
alert("输入参数有误");
return;
}
var query = "/add_card"; # 调用后端add_card函数
var body = JSON.stringify({
"product": product,
"count": card_count,
});
$.post(query, body, function(data, status) {
var data = JSON.parse(data);
var data_ = data.data;
var card_list_text = "";
var line_size = 1;
for (var i = 0; i < data_.length; i++) {
card_list_text += "<tr><td>" + data_[i] + "</td></tr>";
}
$("#card_list").html(card_list_text); // 将生成的卡密输出到页面
})
})
运行工程
执行python3 faka_demo_1.py ,使用浏览器访问http://127.0.0.1:8080 执行结果如图
|